Liquid✨ Premium

Card Morph

Une carte compacte (pastille, nom, rôle) qui, au clic, s'élargit de 200 à 300 px avec un rebond et déroule un paragraphe et trois chiffres en dégradé ; un second clic la replie. Le contenu se révèle dans la même carte, sans changer de page : l'en-tête est un vrai bouton qui dit si la carte est ouverte, et les détails repliés sont cachés aux lecteurs d'écran.

CSSJSLayout

Mis à jour le

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

3 exemples d'usage

Carte d'un cépage — page « Nos vignes » d'un domaine viticole — Card Morph exemple 1

① Carte d'un cépage — page « Nos vignes » d'un domaine viticole

QuandRepliée, la carte montre la pastille « CF » et « Cabernet franc — parcelle des Perrières » ; dépliée, la description du terroir et trois chiffres : 2,4 hectares, 45 ans de vignes, 38 hl/ha.
PourquoiLes trois chiffres en bas de la carte dépliée sont prévus par le code : le curieux les ouvre, les autres lisent juste le nom.
RéglagesTeintes bordeaux et or : fond de carte rgba(190,24,93,.22) → rgba(234,179,8,.08), pastille #9f1239 → #e11d48, chiffres en dégradé #fbbf24 → #f472b6 ; carte posée en haut à gauche pour s'ouvrir vers la droite et vers le bas.
Exposant du salon des métiers d'art — fiche d'un forgeron coutelier — Card Morph exemple 2

② Exposant du salon des métiers d'art — fiche d'un forgeron coutelier

QuandRepliée : « Yann Le Goff — coutelier, stand B12 » ; dépliée : sa présentation et « 18 ans de forge, 6 aciers, 2 démonstrations par jour », à côté du plan de l'allée.
PourquoiLa carte s'agrandit sur place dans la liste des exposants : on garde sa position dans la liste au lieu d'ouvrir une autre page.
RéglagesTeintes cuivre : fond rgba(234,88,12,.18), pastille #78350f → #ea580c, chiffres #fdba74 → #e7e5e4 ; paragraphe de deux lignes pour rester sous les 200 px de max-height.
Producteur du panier de la semaine — page d'une AMAP — Card Morph exemple 3

③ Producteur du panier de la semaine — page d'une AMAP

QuandRepliée : « Ferme du Bois-Joli — légumes » ; dépliée : un mot de la maraîchère et « 14 km, 3 ha, bio depuis 2011 », au-dessus du contenu du panier du jeudi.
PourquoiLe panier liste plusieurs producteurs : chaque carte reste petite jusqu'au clic, la page reste courte.
RéglagesTeintes vertes : fond rgba(101,163,13,.2), pastille #3f6212 → #84cc16, chiffres #bef264 → #fde047 ; les autres producteurs en cartes compactes dans la colonne de droite.

Comment ça marche

La carte .card-morph mesure 200 px de large, avec 20 px de marge intérieure, un fond violet translucide et des coins de 16 px. Son en-tête .card-header est un <button> qui contient la pastille de 40 px (initiales sur dégradé violet-rose), le nom et le rôle. Dessous, .card-details attend replié : max-height: 0, opacity: 0. Au clic, le script bascule .expanded sur la carte : elle passe à 300 px avec transition: .6s cubic-bezier(.68, -.55, .27, 1.55), un rebond qui la fait légèrement rétrécir puis dépasser sa largeur ; les détails s'ouvrent (max-height jusqu'à 200 px en 0,6 s, opacité et marge en 0,4 s).

Toute la carte écoute le clic, mais seul l'en-tête est un bouton. C'est un choix : un bouton qui engloberait le paragraphe et les chiffres ferait lire tout ce texte comme son nom. Au clavier, Tab atteint l'en-tête, Entrée ou Espace déclenche un clic qui remonte jusqu'à la carte, et aria-expanded passe à true ou false. Repliés, les détails sont aussi rendus invisibles (visibility: hidden, appliqué 0,6 s après le début de la fermeture pour ne pas couper l'animation) : un lecteur d'écran ne lit pas un texte caché à l'écran.

Les trois chiffres sont écrits en dégradé violet-cyan par background-clip: text (avec sa forme -webkit-) et -webkit-text-fill-color: transparent. La hauteur passe par max-height, parce qu'une hauteur auto ne s'anime pas partout : 200 px laissent la place à un paragraphe de trois ou quatre lignes et à la rangée de chiffres ; un contenu plus long serait coupé, montez alors la valeur. Le script, une dizaine de lignes, parcourt toutes les .fx-0406-root .card-morph : plusieurs cartes cohabitent, chacune avec son état.

Accessibilité

  • Clavier : mesuré dans Chromium 151 et Firefox 153, Tab atteint l'en-tête, Entrée comme Espace ouvre puis referme la carte, et aria-expanded suit. L'anneau de focus (2 px violet, décalé de 4 px) reste dans la marge de la carte. Dans Safari, Tab ne s'arrête sur les boutons que si le réglage clavier le demande (ou avec Option+Tab).
  • Lecteurs d'écran : l'en-tête est annoncé « Alice Laurent Designer UI/UX, bouton, réduit » ; la pastille d'initiales est masquée (aria-hidden). Repliés, le paragraphe et les chiffres ne sont pas lus.
  • Mouvement réduit : sous prefers-reduced-motion: reduce, la carte prend directement 300 px, sans rebond, et les détails apparaissent en fondu de 0,3 s. Mesuré : plus aucune image ne change après 300 ms.
  • Contraste : le paragraphe est blanc à 60 % sur fond sombre (environ 7:1) ; les intitulés des chiffres, blancs à 40 %, descendent vers 4:1. Gardez-les courts, ou montez leur opacité si votre fond est plus clair.

Compatibilité navigateur

CSS (transitions de width, max-height, opacity ; background-clip: text) + 0,5 Ko de JavaScript, aucune dépendance. Mesuré image par image dans Chromium 151, Firefox 153 et WebKit 26 : même élargissement avec rebond, même déroulé des détails, même arrêt sous mouvement réduit. Le fond en dégradé de la carte ne s'anime pas : il change d'un coup, sous la largeur qui, elle, glisse.

Chrome 60+✓ Complet
Firefox 60+✓ Complet
Safari 12+✓ Complet (Tab selon le réglage clavier)
Edge 79+✓ Complet
Mobile iOS 12+✓ Complet (au doigt)
Android Chrome 60+✓ Complet (au doigt)

Sans JavaScript, la carte reste repliée et ses détails ne sont pas accessibles : si le paragraphe et les chiffres comptent, prévoyez un lien vers une page complète. Sans background-clip: text, les chiffres s'affichent en dégradé plein (des rectangles colorés) : remplacez-les alors par une couleur unie.

Le code

Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :

index.html — structure
<div class="fx-0406-root">
  <div class="card-morph-wrapper">
    <div class="card-morph">
      <button type="button" class="card-header" aria-expanded="false">
        <span class="card-avatar" aria-hidden="true">AL</span>
        <span class="card-id"><span class="card-name">…</span><span class="card-role">…</span></span>
      </button>
      <div class="card-details">
        <p>…</p>
        <div class="card-stats">
          <div class="card-stat"><div class="card-stat-value">142</div><div class="card-stat-label">…</div></div> … (3 chiffres)
        </div>
      </div>
    </div>
  </div>
</div>

Paiement unique, sans abonnement — le code est à toi pour toujours

Personnaliser

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

Option / propriétéDéfautEffet
Largeurs (CSS — width de .card-morph et de .expanded) 200 px repliée, 300 px dépliée L'écart fait l'effet : 220 → 340 px pour un texte plus long. Sur mobile, width: min(300px, 100%) évite que la carte dépliée dépasse l'écran.
Hauteur maximale des détails (CSS — max-height de .expanded .card-details) 200 px Montez-la si votre paragraphe dépasse quatre lignes (300 px pour six lignes). Une valeur trop grande retarde la fermeture : la transition part de cette valeur, pas de la hauteur réelle.
Rebond (CSS — transition: .6s cubic-bezier(.68, -.55, .27, 1.55)) 0,6 s, recul puis dépassement .4s ease donne une ouverture sans rebond. Gardez la même durée que max-height pour que largeur et hauteur arrivent ensemble.
Teintes (CSS — background de la carte, de .card-avatar et de .card-stat-value) violet #a855f7, cyan #06b6d4, rose #ec4899 Accordez les trois à votre marque. La carte dépliée prend un fond un peu plus dense et une ombre de 60 px : gardez cet écart, il dit qu'elle est ouverte.
Contenu (HTML — .card-details) un paragraphe et trois chiffres Mettez-y ce que vous voulez (liste, lien, bouton). Un lien ou un bouton placé dans les détails reçoit le clic et le transmet à la carte : ajoutez e.stopPropagation() sur son clic pour qu'il ne replie pas la carte.

FAQ

Parce qu'un bouton prend tout son contenu comme nom : une carte entière en bouton serait annoncée avec le paragraphe et les chiffres, à chaque passage du clavier. L'en-tête porte un nom court (le nom et le rôle), aria-expanded dit l'état, et la souris peut toujours cliquer n'importe où sur la carte, puisque c'est la carte qui écoute le clic.
Parce qu'une transition de height: 0 à height: auto ne s'anime pas dans tous les navigateurs : elle saute. max-height de 0 à 200 px s'anime partout, au prix d'une limite : un contenu plus haut que 200 px est coupé, et la fermeture commence par « consommer » l'écart entre 200 px et la hauteur réelle. Chrome 129 sait animer vers auto avec interpolate-size: allow-keywords ; tant que Firefox et Safari ne suivent pas, max-height reste le choix qui marche partout.
Avatar Morph part d'un rond de 80 px qui devient une carte au survol (ou au focus), en CSS pur, pour une information courte : un nom, un rôle, un badge. Card Morph part d'une carte déjà rectangulaire, s'ouvre au clic et déroule un vrai contenu, paragraphe et chiffres. Choisissez Avatar Morph pour une rangée de visages qu'on survole ; Card Morph pour une liste de fiches qu'on ouvre une à une.