Cartes✨ Premium

Grid to List Toggle

Bascule fluide grille ↔ liste avec technique FLIP — les items se repositionnent par animation physique, révélant les libellés au passage.

CSSGridFLIP

Vous aurez accès à la démo interactive avec un compte gratuit.

Cet effet fait partie d'Effect.Labs — 811 effets vanilla, une partie gratuite, une partie premium. Cartes comprend 41 effets, dont 6 gratuits. Découvrir la catégorie →

3 exemples d'usage

Sidebar d'application — Raccourcis en grille ou menu condensé — Grid to List Toggle exemple 1

① Sidebar d'application — Raccourcis en grille ou menu condensé

QuandUn tableau de bord propose deux modes d'affichage : une grille d'icônes pour la navigation rapide au pointeur, et une liste compacte avec libellés pour les utilisateurs clavier ou les écrans étroits.
PourquoiLe FLIP masque la rigidité de CSS Grid en donnant l'impression que chaque item se déplace physiquement vers sa nouvelle position — l'interaction est perçue comme naturelle plutôt que téléportée.
Réglages3 colonnes par défaut (repeat(3, 1fr)), transition à 0.35s pour une réponse plus vive, gap: 12px pour aérer la grille, icône à 32px en grille et 24px en liste (valeurs par défaut).
Catalogue produits — Vue galerie ↔ vue liste de comparaison — Grid to List Toggle exemple 2

② Catalogue produits — Vue galerie ↔ vue liste de comparaison

QuandUne page produit e-commerce offre deux modes : galerie pour la découverte visuelle (vignettes larges), liste pour la comparaison rapide (nom + prix côte à côte).
PourquoiLa révélation du libellé via max-width: 0 → 200px avec opacity donne l'impression que le texte se déroule depuis la vignette — plus élégant qu'un simple display: none.
Réglagesrepeat(4, 1fr) pour 4 colonnes sur desktop, icône agrandie à 40 × 40 px en grille, --primary: #10b981 pour une teinte verte brand, max-width: 280px pour des libellés de produit plus longs.
Base de connaissances — Cartes de rubriques ou index compact — Grid to List Toggle exemple 3

③ Base de connaissances — Cartes de rubriques ou index compact

QuandUn centre d'aide ou une documentation interne permet de basculer entre vue cartes (navigation visuelle) et liste dense (lecture rapide des titres).
PourquoiLe FLIP maintient l'orientation spatiale de l'utilisateur — il voit chaque rubrique « se repositionner » plutôt que la liste se reconstruire de zéro, ce qui réduit la désorientation au changement de mode.
Réglagesrepeat(2, 1fr) pour 2 colonnes larges en grille, transition à 0.5s (valeur par défaut) pour une animation ample, border-radius: 12px sur les items, padding: 16px pour des cartes respirantes.

Comment ça marche

Le conteneur utilise CSS Grid : en mode grille, grid-template-columns: repeat(3, 1fr) dispose 6 items sur 2 rangées. Un clic ajoute la classe .list-mode qui bascule sur grid-template-columns: 1fr — une colonne pleine largeur. Problème : grid-template-columns n'est pas une propriété interpolable dans les navigateurs actuels, donc CSS ne peut pas animer ce changement. C'est le JS qui prend le relais avec la technique FLIP.

La technique FLIP (First-Last-Invert-Play) opère en quatre phases sur chaque .grid-list-item : First — lire les coordonnées courantes avec getBoundingClientRect() ; Last — appliquer la classe .list-mode (le layout Grid recalcule immédiatement) ; Invert — calculer le delta δx/δy entre ancienne et nouvelle position, puis forcer transform: translate(δx, δy) sans transition pour ramener l'item à son emplacement visuel d'origine ; Play — dans un requestAnimationFrame, réactiver la transition CSS et retirer le transform, laissant l'item glisser vers sa vraie destination.

En parallèle, deux micro-transitions CSS s'opèrent sur chaque item : le libellé (.item-text) passe de opacity: 0; max-width: 0 en grille à opacity: 1; max-width: 200px en liste, se déroulant depuis l'icône ; l'icône (.item-icon) réduit de 32 × 32 px à 24 × 24 px. Ces deux transitions partagent le même cubic-bezier(.4, 0, .2, 1) que le FLIP, synchronisant visuellement l'entrée du texte avec le déplacement de l'item.

La fonction setGridList(bouton, mode) est déclarée en global (hors IIFE) pour rester appelable depuis les attributs onclick HTML. Elle retrouve le groupe de toggles via t.parentElement.querySelectorAll('.morph-toggle') pour mettre à jour l'état .active — ce qui permet de câbler plusieurs instances sur la même page en leur fournissant chacune un conteneur cible distinct.

Accessibilité

  • prefers-reduced-motion absent : ni le CSS ni le JS ne vérifient cette préférence OS — l'animation FLIP et les transitions max-width/opacity s'exécutent même si l'utilisateur a activé « Réduire le mouvement ». À ajouter avant un usage en production accessible.
  • Les boutons toggle sont de vrais <button> HTML — activables au clavier (Tab, Entrée, Espace) sans JS supplémentaire.
  • Aucun aria-pressed sur les boutons toggle : l'état actif (classe .active) n'est pas exposé aux lecteurs d'écran.
  • Le conteneur .grid-list-container ne porte ni role ni aria-label — la sémantique de la région n'est pas déclarée.
  • La couleur #a5b4fc des libellés visibles en mode liste sur fond sombre (~rgba(99,102,241,.15) sur #0a0a0f) atteint un ratio de contraste ≥ 5:1 — WCAG AA satisfait pour le texte normal.

Compatibilité navigateur

Nécessite CSS Grid Level 1 et requestAnimationFrame — supportés dans tous les navigateurs modernes. La propriété grid-template-columns n'est pas interpolable nativement : la fluidité repose entièrement sur la technique FLIP côté JS.

Chrome 110+✓ Complet
Firefox 110+✓ Complet
Safari 16+✓ Complet
Edge 110+✓ Complet
Mobile iOS✓ Touch OK
Android Chrome✓ Complet

Si JavaScript est désactivé, les boutons toggle ne fonctionnent pas et la vue reste figée en mode grille par défaut — le contenu reste lisible et la mise en page ne casse pas.

Le code

Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :

index.html — structure
<div class="demo-preview">
  <div class="morph-toggle-group">
    <button class="morph-toggle active" onclick="setGridList(this, 'grid')">Grid</button>
    <button class="morph-toggle" onclick="setGridList(this, 'list')">List</button>
  </div>
  <div class="grid-list-container" id="gridListDemo">
    <div class="grid-list-item">
      <div class="item-icon"></div>
      <span class="item-text">Label</span>
    </div>
    <!-- répétez .grid-list-item autant de fois que nécessaire -->
  </div>
</div>
🔒 Débloquer le code complet — à partir de 2,99 € le 1er mois

HTML + CSS + JS complet, prêt à coller — avec des centaines d'effets premium.

Personnaliser

Options passées à l'API ou attributs data-* :

Option / propriétéDéfautEffet
--primary #6366f1 Variable CSS contrôlant la couleur des boutons toggle, les bordures et le dégradé de fond des items. Remplacez par votre couleur brand.
grid-template-columns repeat(3, 1fr) Colonnes en mode grille. Changez 3 en 2 (items larges), 4 (items compacts) ou 6 (icônes seules sans texte).
transition: .5s 0.5s cubic-bezier(.4, 0, .2, 1) Durée et easing du FLIP et des transitions max-width/opacity. 0.3s pour une réponse vive, 0.8s pour un effet cinématique.
.item-icon width/height 32px / 32px (grille), 24px / 24px (liste) Taille de l'icône dans chaque mode. Passez à 40px en grille pour des icônes plus visibles, ou 20px en liste pour une vue ultra-compacte.
.item-text max-width 200px (mode liste) Largeur maximale du libellé révélé en liste. De 120px pour des labels courts à 320px pour des titres longs.
gap 8px Espacement entre les items (les deux modes). 12–16px pour une mise en page aérée, 4px pour une liste ultra-dense.
.grid-list-item padding 12px Rembourrage interne de chaque item. 16–20px pour des items respirants avec grandes icônes, 8px pour une liste compacte.
.grid-list-item border-radius 8px 4px pour un style rectangulaire strict, 12px pour des cartes douces, 50% (avec items carrés et icône seule) pour des pastilles circulaires.

FAQ

grid-template-columns n'est pas une propriété interpolable — les navigateurs ne savent pas calculer les états intermédiaires entre repeat(3, 1fr) et 1fr. La technique FLIP contourne cela : elle mesure les positions avant et après le changement de layout, déplace instantanément chaque item avec transform: translate(δx, δy) pour le ramener visuellement à son ancienne position, puis retire le transform dans un requestAnimationFrame — la transition CSS prend le relais et donne l'illusion d'un glissement physique.
La fonction setGridList cible en dur document.getElementById('gridListDemo'). Pour plusieurs instances, dupliquez la structure HTML avec un id différent par conteneur, puis créez une version de la fonction spécifique à chaque id — ou adaptez-la pour traverser le DOM depuis le bouton : t.closest('.votre-wrapper').querySelector('.grid-list-container') avant d'appeler le reste de la logique FLIP.
Oui — les boutons <button> HTML natifs répondent aux événements touch sans configuration supplémentaire. Il n'y a pas de geste de swipe intégré ; si vous souhaitez déclencher la bascule au glisser, ajoutez un touchstart ou pointerdown sur le conteneur et appelez setGridList manuellement.