bêta

Flip Card .mv-flip-card

Carte à deux faces qui se retourne en 3D au survol, au focus clavier, au toucher ou au clic, en se soulevant vers le spectateur à mi-rotation, avec une lumière qui décroît sur la face qui s’éloigne ; seule la face visible est active pour Tab, les pointeurs et les lecteurs d’écran.

Catégorie3D
TypeCSS seul (.mv-flip-card)
Statutbêta
Keywordsflip, card, 3d, rotate, flashcard, hover, backface, keyboard, touch

When to use

  • A card needs a second face for a bio, plan details or specs that stays reachable by keyboard and touch
  • Flashcards or quiz tiles should flip to reveal an answer on click, tap, Enter or Space
  • A compact grid must hold twice the content without changing its layout

Avoid when

  • The detail view needs more room than the card footprint → use Expandable Card instead
  • The faces should swap through a dissolving pixel grid rather than a 3D rotation → use Pixel Transition instead
  • The back face holds content every visitor must read, such as prices, terms or errors

Installation

node scripts/add.mjs flip-card --out ./src/marvelous

Agent IA avec le serveur MCP de Marvelous UI : install_components({ slugs: ["flip-card"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).

Fichiers copiés (dépendances comprises) : tokens/tokens.css, core/base.css, core/dom.js, core/motion.js, core/observe.js, components/flip-card/flip-card.css, components/flip-card/flip-card.js.

Utilisation

Balisage de référence : partez de celui-ci et personnalisez-le avec les attributs, data-* et les variables CSS :

<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,17rem));gap:1.75rem;justify-content:center;width:100%">
  <!-- 1. Hover (default): mouse hover, keyboard focus or a tap -->
  <figure style="margin:0;display:grid;gap:.6rem">
    <div class="mv-flip-card" aria-label="Team member: Amara Okafor">
      <div class="mv-flip-card-inner">
        <div class="mv-flip-card-front" style="display:grid;grid-template-rows:7rem auto;min-height:12rem">
          <div aria-hidden="true" style="position:relative;background:radial-gradient(90% 120% at 15% 0%,oklch(0.78 0.14 60),transparent 60%),linear-gradient(140deg,oklch(0.55 0.17 25),oklch(0.36 0.12 300))">
            <span style="position:absolute;left:1rem;bottom:-1.4rem;width:3.2rem;height:3.2rem;border-radius:50%;display:grid;place-items:center;font:600 1.05rem/1 var(--mv-font-sans);color:#fff;background:oklch(0.3 0.08 300);box-shadow:0 0 0 3px var(--mv-surface)">AO</span>
          </div>
          <div style="padding:1.7rem 1rem .95rem">
            <strong style="display:block">Amara Okafor</strong>
            <small style="color:var(--mv-fg-muted)">Staff designer · Lagos</small>
          </div>
        </div>
        <div class="mv-flip-card-back" style="display:grid;align-content:center;gap:.6rem;padding:1.1rem 1.15rem;font-size:.85rem">
          <strong style="font-size:.95rem">About Amara</strong>
          <p style="margin:0;color:var(--mv-fg-muted);line-height:1.5">Leads the design system. Previously built payment flows used by 4 million people across West Africa.</p>
          <span style="display:flex;justify-content:space-between;color:var(--mv-fg-muted)">Joined<b style="color:var(--mv-fg)">March 2022</b></span>
        </div>
      </div>
    </div>
    <figcaption style="color:var(--mv-fg-muted);text-align:center;font-size:.8rem">Hover, focus or tap · Y axis</figcaption>
  </figure>

  <!-- 2. Click: a plain card becomes a toggle button whose name follows the visible face -->
  <figure style="margin:0;display:grid;gap:.6rem">
    <div class="mv-flip-card" data-trigger="click" data-direction="reverse">
      <div class="mv-flip-card-inner">
        <div class="mv-flip-card-front" style="min-height:12rem;display:grid;place-items:center;text-align:center;padding:1.25rem;background:var(--mv-bg-subtle)">
          <div>
            <span style="font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;color:var(--mv-fg-subtle)">Space quiz · 3 of 10</span>
            <p style="margin:.5rem 0 .35rem;font:650 1.2rem/1.3 var(--mv-font-sans);letter-spacing:-.01em">When did Apollo 11 land on the Moon?</p>
            <span style="font-size:.75rem;color:var(--mv-fg-muted)">Click or press Enter</span>
          </div>
        </div>
        <div class="mv-flip-card-back" style="min-height:12rem;display:grid;align-content:center;gap:.35rem;padding:1.25rem;background:var(--mv-accent);color:var(--mv-fg-on-accent)">
          <span style="font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;opacity:.8">Answer</span>
          <p style="margin:0;font:700 1.6rem/1.1 var(--mv-font-sans)">July 20, 1969</p>
          <p style="margin:0;font-size:.8rem;opacity:.85;line-height:1.45">The Eagle lander touched down in the Sea of Tranquility.</p>
        </div>
      </div>
    </div>
    <figcaption style="color:var(--mv-fg-muted);text-align:center;font-size:.8rem">data-trigger="click" · Enter, Space, Escape</figcaption>
  </figure>

  <!-- 3. X axis, links on the faces: [data-flip] buttons do the flipping -->
  <figure style="margin:0;display:grid;gap:.6rem">
    <div class="mv-flip-card" data-trigger="click" data-axis="x">
      <div class="mv-flip-card-inner">
        <div class="mv-flip-card-front" style="display:grid;align-content:space-between;gap:.8rem;padding:1.1rem;min-height:12rem">
          <div>
            <small style="color:var(--mv-fg-muted)">Pro plan</small>
            <p style="margin:.2rem 0 0;font:700 1.9rem/1 var(--mv-font-sans);letter-spacing:-.02em">$24<span style="font-size:.85rem;font-weight:500;color:var(--mv-fg-muted)"> / month</span></p>
          </div>
          <p style="margin:0;font-size:.85rem;color:var(--mv-fg-muted);line-height:1.45">Unlimited projects, priority support and a shared workspace for your team.</p>
          <div style="display:flex;gap:.5rem;justify-content:space-between">
            <a class="mv-button" data-size="sm" href="#flip-card">Start free trial</a>
            <button type="button" class="mv-button" data-variant="outline" data-size="sm" data-flip>What's included</button>
          </div>
        </div>
        <div class="mv-flip-card-back" style="display:grid;align-content:space-between;gap:.6rem;padding:1.1rem;min-height:12rem;font-size:.82rem">
          <ul style="margin:0;padding-left:1.1rem;display:grid;gap:.3rem;line-height:1.4">
            <li>Unlimited projects and guests</li>
            <li>Version history for 1 year</li>
            <li>SSO and audit log</li>
            <li>Support reply within 4 hours</li>
          </ul>
          <div style="display:flex;justify-content:flex-end">
            <button type="button" class="mv-button" data-variant="ghost" data-size="sm" data-flip>Back to pricing</button>
          </div>
        </div>
      </div>
    </div>
    <figcaption style="color:var(--mv-fg-muted);text-align:center;font-size:.8rem">data-axis="x" · data-flip buttons</figcaption>
  </figure>
</div>

API

Attributes

NameTypeDefaultDescription
data-triggerhover | focus | clickhoverhover: mouse hover, keyboard focus on the card or a tap; focus: keyboard focus or a tap; click: click, tap, Enter or Space.
data-axisy | xyRotation axis.
data-directionreverseTurns the other way.
data-flippedbooleanFlipped state, set by the script or by hand (both keep the faces in sync).
data-flipbooleanOn a button inside the card: flips it, and focus moves to the matching button on the face that turns in. Use it when the faces hold links.
data-flip-readybooleanSet by the script once the card is wired; until then the CSS alone flips on hover and focus.

Methods

NameDescription
flip(card, force?)JS export: flips a card (force = true/false to pick the face).

Events

NameDescription
mv-flipdetail: { flipped } after a JS flip.

CSS classes

NameDescription
mv-flip-cardContainer (perspective).
mv-flip-card-inner3D pivot (direct child).
mv-flip-card-front / mv-flip-card-backFaces, stacked in the same grid cell.

CSS variables

NameDefaultDescription
--mv-flip-card-durationvar(--mv-duration-slower)Turn duration.
--mv-flip-card-easingslight overshootTurn easing curve.
--mv-flip-card-perspective1200pxPerspective depth.
--mv-flip-card-radiusvar(--mv-radius-xl)Face radius.
--mv-flip-card-lift40pxHow far the card rises toward the viewer mid-turn (0 to disable).
--mv-flip-card-shade0.32Darkness of the face turning away (0 to disable).

Accessibility

The hidden face is inert and aria-hidden: skipped by Tab, pointers and screen readers. A hover or focus card with no [data-flip] button becomes focusable (tabindex=0, role=group, its back face as aria-describedby) and turns on keyboard focus; give it an aria-label. A plain click card becomes a toggle button (role=button, aria-pressed, Enter/Space) whose name follows the visible face, so leave aria-label off. With links on the faces, use [data-flip] buttons; focus follows to the face that turns in. Escape returns to the front. Touch: a tap flips. Mouse hover only on fine pointers. Reduced motion: the faces crossfade in place. Forced colors: faces get a system outline.

Cette page a été traduite par IA. Signaler un problème de traduction