Beta
Flip Card .mv-flip-card
Zweiseitige Karte, die sich bei Hover, Tastaturfokus, Tippen oder Klick in 3D dreht, sich mitten in der Drehung zum Betrachter hebt, während das Licht von der abgewandten Seite abfällt; nur die sichtbare Seite ist für Tab, Zeiger und Screenreader aktiv.
| Kategorie | 3D |
|---|---|
| Typ | Nur CSS (.mv-flip-card) |
| Status | Beta |
| Keywords | flip, 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/marvelousKI-Agent mit dem MCP-Server von Marvelous UI: install_components({ slugs: ["flip-card"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).
Kopierte Dateien (inklusive Abhängigkeiten): 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.
Verwendung
Referenz-Markup zum Starten und Anpassen mit Attributen, data-* und CSS-Variablen:
<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
| Name | Typ | Default | Description |
|---|---|---|---|
data-trigger | hover | focus | click | hover | hover: mouse hover, keyboard focus on the card or a tap; focus: keyboard focus or a tap; click: click, tap, Enter or Space. |
data-axis | y | x | y | Rotation axis. |
data-direction | reverse | Turns the other way. | |
data-flipped | boolean | Flipped state, set by the script or by hand (both keep the faces in sync). | |
data-flip | boolean | On 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-ready | boolean | Set by the script once the card is wired; until then the CSS alone flips on hover and focus. |
Methods
| Name | Description |
|---|---|
flip(card, force?) | JS export: flips a card (force = true/false to pick the face). |
Events
| Name | Description |
|---|---|
mv-flip | detail: { flipped } after a JS flip. |
CSS classes
| Name | Description |
|---|---|
mv-flip-card | Container (perspective). |
mv-flip-card-inner | 3D pivot (direct child). |
mv-flip-card-front / mv-flip-card-back | Faces, stacked in the same grid cell. |
CSS variables
| Name | Default | Description |
|---|---|---|
--mv-flip-card-duration | var(--mv-duration-slower) | Turn duration. |
--mv-flip-card-easing | slight overshoot | Turn easing curve. |
--mv-flip-card-perspective | 1200px | Perspective depth. |
--mv-flip-card-radius | var(--mv-radius-xl) | Face radius. |
--mv-flip-card-lift | 40px | How far the card rises toward the viewer mid-turn (0 to disable). |
--mv-flip-card-shade | 0.32 | Darkness 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.