bêta
Pixel Transition <mv-pixel-transition>
Passe d’une face à l’autre à travers une grille de pixels : des pixels carrés grandissent sur la première face dans un ordre aléatoire, radial (depuis le pointeur), diagonal ou par rangées, les faces s’échangent sous une couverture complète, puis les pixels rétrécissent et disparaissent. Une seule valeur de progression pilote chaque image, si bien qu’un survol interrompu revient en arrière en douceur.
| Catégorie | Transitions |
|---|---|
| Type | Web Component (<mv-pixel-transition>) |
| Statut | bêta |
| Keywords | safe-rewrite, pixel, transition, reveal, hover, card, swap, canvas, retro |
When to use
- A card should swap to a second face through a retro pixel dissolve on hover or focus
- A team or product tile should reveal hidden details with a radial pixel effect from the pointer
- Two images or states should toggle manually with a playful, interruptible pixel transition
Avoid when
- A two-sided card should flip in 3D rather than dissolve → use Flip Card instead
- Users should compare two images side by side with a draggable divider → use Image Compare instead
- The hidden face holds essential information on touch-first pages; hover reveals are easy to miss
Installation
node scripts/add.mjs pixel-transition --out ./src/marvelousAgent IA avec le serveur MCP de Marvelous UI : install_components({ slugs: ["pixel-transition"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).
Fichiers copiés (dépendances comprises) : tokens/tokens.css, core/base.css, core/canvas.js, core/dom.js, core/element.js, core/focus.js, core/motion.js, components/pixel-transition/pixel-transition.js, components/pixel-transition/pixel-transition.css.
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(3,minmax(0,1fr));gap:1rem;width:100%;max-width:820px">
<mv-pixel-transition grid="10" colors="oklch(0.97 0.02 85), oklch(0.88 0.08 70), oklch(0.8 0.12 55)" style="aspect-ratio:3/4">
<div style="display:grid;place-items:center;background:linear-gradient(160deg,oklch(0.62 0.19 285),oklch(0.45 0.17 300));color:white;text-align:center;padding:1rem">
<div><p style="margin:0;font:800 3rem/1 var(--mv-font-display)">?</p><p style="margin:.5rem 0 0;font-size:.85rem;opacity:.85">Hover the card</p></div>
</div>
<div style="display:grid;align-content:end;gap:.35rem;padding:1.1rem;background:linear-gradient(180deg,transparent 30%,oklch(0 0 none / .55)),radial-gradient(circle at 30% 30%,oklch(0.85 0.12 80),oklch(0.55 0.16 40));color:white">
<strong style="font-size:1.05rem">Maya Chen</strong>
<span style="font-size:.8rem;opacity:.9">Art Director · Tokyo</span>
</div>
</mv-pixel-transition>
<mv-pixel-transition trigger="click" pattern="radial" grid="14" duration="800" colors="oklch(0.72 0.15 160), oklch(0.62 0.14 175), oklch(0.8 0.12 140)" style="aspect-ratio:3/4">
<div style="display:grid;place-items:center;background:var(--mv-bg-muted);border:1px solid var(--mv-border);border-radius:inherit;text-align:center;padding:1rem">
<div><p style="margin:0;font-weight:600">Pro plan</p><p style="margin:.35rem 0 0;font-size:.8rem;color:var(--mv-fg-muted)">Click to see the price</p></div>
</div>
<div style="display:grid;place-items:center;background:oklch(0.3 0.06 170);color:white;text-align:center;padding:1rem">
<div><p style="margin:0;font:800 2.4rem/1 var(--mv-font-display)">$19</p><p style="margin:.35rem 0 0;font-size:.8rem;opacity:.8">per month, cancel anytime</p></div>
</div>
</mv-pixel-transition>
<mv-pixel-transition pattern="diagonal" grid="16" duration="600" colors="#0f172a, #1e293b, #334155" style="aspect-ratio:3/4">
<div style="display:grid;place-items:center;background:oklch(0.95 0.03 90);color:oklch(0.3 0.05 60);padding:1rem;text-align:center">
<p style="margin:0;font:700 1.35rem/1.2 var(--mv-font-display)">Day</p>
</div>
<div style="display:grid;place-items:center;background:oklch(0.2 0.04 265);color:oklch(0.9 0.05 265);padding:1rem;text-align:center">
<p style="margin:0;font:700 1.35rem/1.2 var(--mv-font-display)">Night ✦</p>
</div>
</mv-pixel-transition>
</div>API
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
trigger | hover | click | manual | hover | Trigger (hover: also keyboard focus, and a tap on touch screens; click: click, Enter or Space; manual: toggle()/show() or the flipped attribute). |
pattern | random | radial | diagonal | rows | random | Order in which pixels appear (radial starts from where the pointer entered or clicked, the center otherwise). |
grid | number | 12 | Number of pixel columns, 2 to 60 (square pixels, rows follow). |
duration | number | 700 | Total duration of one switch (ms). |
colors | list of CSS colors | var(--mv-pixel-transition-color) | One or more colors (tokens accepted, they follow the theme), spread across the pixels. |
flipped | boolean | Back face shown (reflected by the component, writable). | |
data-state | front | back | Set by the component. |
Methods
| Name | Description |
|---|---|
toggle() | Switches to the other face. |
show(face) | Shows “front” or “back”. |
Events
| Name | Description |
|---|---|
mv-change | detail: { face, flipped }. At the moment the faces swap. |
Content structure
| Name | Description |
|---|---|
(child 1 / child 2) | Front face, then back face; the element takes the size of the larger one. |
CSS variables
| Name | Default | Description |
|---|---|---|
--mv-pixel-transition-color | var(--mv-fg) | Default pixel color. |
Accessibility
The hidden face is inert and aria-hidden. Without focusable content, the element becomes focusable (Enter/Space); in click mode it has role=button and aria-pressed. In hover mode, keyboard focus also reveals the back face and a tap toggles. Reduced motion: instant swap, no pixels. Forced colors: no painted pixels, the faces swap half-way. The frame loop only runs during a switch.