ExklusivBeta
Exploded View <mv-exploded>
Eine 3D-Explosionsansicht jeder beliebigen Live-Oberfläche: Jede Box wird zu einer Ebene, die entsprechend ihrer visuellen Tiefe angehoben wird (unsichtbare Wrapper fügen keine Etage hinzu), die ganze Baugruppe kippt in eine isometrische Pose, lässt sich per Ziehen oder Tastatur umkreisen, isoliert beim Hover eine Ebene (Tag, Klassen, Größe), beschriftet Ebenen mit Hinweislinien, setzt sich dann mit Federn pro Etage wieder zusammen und stellt die ursprünglichen Styles Byte für Byte wieder her.
| Kategorie | 3D |
|---|---|
| Typ | Web Component (<mv-exploded>) |
| Status | Beta |
| Keywords | exclusive, 3d, exploded-view, anatomy, inspector, preserve-3d, layers, landing, devtools, spring |
When to use
- A landing page should reveal the anatomy of a live interface as layered planes in 3D
- A design system or devtools demo needs to show how a component is built, with labeled layers
- A scroll-driven section should explode and reassemble a UI as the visitor passes through
Avoid when
- A flat device frame is enough to present the interface → use Device Mockup instead
- The wrapped interface must stay usable, since clicks are intercepted while it is exploded
- The subtree has hundreds of elements; layer caps protect performance but the view gets cluttered
Installation
node scripts/add.mjs exploded --out ./src/marvelousKI-Agent mit dem MCP-Server von Marvelous UI: install_components({ slugs: ["exploded"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).
Kopierte Dateien (inklusive Abhängigkeiten): tokens/tokens.css, core/base.css, core/dom.js, core/element.js, core/motion.js, core/observe.js, components/exploded/exploded.js, components/exploded/exploded.css.
Verwendung
Referenz-Markup zum Starten und Anpassen mit Attributen, data-* und CSS-Variablen:
<div class="ex-demo">
<style>
.ex-demo { display: grid; grid-template-columns: minmax(0, 340px) minmax(0, 1fr); align-items: center; gap: clamp(16px, 4vw, 56px); min-height: 620px; padding: 32px clamp(20px, 4vw, 56px); box-sizing: border-box; }
@media (max-width: 820px) { .ex-demo { grid-template-columns: 1fr; } }
.ex-eyebrow { margin: 0 0 10px; font: 600 12px/1 var(--mv-font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--mv-accent-fg); }
.ex-copy h2 { margin: 0; font: 750 clamp(1.8rem, 3vw, 2.4rem)/1.05 var(--mv-font-sans); letter-spacing: -.035em; }
.ex-copy > p:not(.ex-eyebrow) { margin: 14px 0 0; color: var(--mv-fg-muted); font-size: .95rem; line-height: 1.55; }
.ex-facts { list-style: none; margin: 22px 0 0; padding: 0; display: grid; gap: 10px; font-size: .88rem; }
.ex-facts li { display: flex; gap: 10px; align-items: baseline; }
.ex-facts b { font: 700 1rem/1 var(--mv-font-sans); min-width: 2.2em; color: var(--mv-fg); }
.ex-facts span { color: var(--mv-fg-muted); }
.ex-keys { margin-top: 22px; font-size: .78rem; color: var(--mv-fg-subtle); }
.ex-keys kbd { font: 600 11px/1 var(--mv-font-mono); padding: 3px 6px; border-radius: 5px; border: 1px solid var(--mv-border-strong); border-bottom-width: 2px; background: var(--mv-surface); color: var(--mv-fg); }
.ex-view { min-height: 540px; display: grid; place-items: center; }
.ex-card { width: min(100%, 340px); border-radius: 22px; background: var(--mv-surface-raised); border: 1px solid var(--mv-border); box-shadow: var(--mv-shadow-xl); overflow: hidden; }
.ex-media { position: relative; height: 176px; background: linear-gradient(180deg, #8ec5ff 0%, #cfe6ff 55%, #f6e7d4 100%); }
.ex-media svg { position: absolute; inset: auto 0 0; width: 100%; height: 120px; }
.ex-badge { position: absolute; top: 14px; left: 14px; padding: 6px 10px; border-radius: 999px; background: oklch(0.99 0 0 / .92); color: oklch(0.25 0.03 270); font: 650 11.5px/1 var(--mv-font-sans); box-shadow: 0 4px 12px oklch(0.2 0.05 260 / .18); }
.ex-fav { position: absolute; top: 10px; right: 10px; width: 36px; height: 36px; border-radius: 50%; border: 0; display: grid; place-items: center; background: oklch(0.99 0 0 / .92); color: oklch(0.62 0.22 20); box-shadow: 0 4px 12px oklch(0.2 0.05 260 / .18); cursor: pointer; }
.ex-fav svg { position: static; width: 18px; height: 18px; }
.ex-body { padding: 16px 18px 18px; display: grid; gap: 10px; }
.ex-host { position: relative; display: flex; align-items: center; gap: 10px; margin-top: -38px; }
.ex-avatar { width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; background: linear-gradient(135deg, oklch(0.7 0.15 40), oklch(0.6 0.18 350)); color: white; font: 700 14px/1 var(--mv-font-sans); border: 3px solid var(--mv-surface-raised); box-shadow: var(--mv-shadow-md); }
.ex-host small { margin-top: 30px; font-size: 12px; color: var(--mv-fg-muted); }
.ex-body h3 { margin: 2px 0 0; font: 700 1.15rem/1.2 var(--mv-font-sans); letter-spacing: -.02em; }
.ex-meta { margin: -4px 0 0; font-size: .82rem; color: var(--mv-fg-muted); }
.ex-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.ex-tags span { padding: 4px 9px; border-radius: 999px; background: var(--mv-bg-muted); border: 1px solid var(--mv-border); font-size: 11.5px; color: var(--mv-fg-muted); }
.ex-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 4px; padding-top: 12px; border-top: 1px solid var(--mv-border); }
.ex-price { font-size: .82rem; color: var(--mv-fg-muted); }
.ex-price b { font: 750 1.25rem/1 var(--mv-font-sans); color: var(--mv-fg); letter-spacing: -.02em; }
</style>
<div class="ex-copy">
<p class="ex-eyebrow">Design system · Refuge</p>
<h2>How it’s built</h2>
<p>This booking card isn’t a mockup: it’s the real DOM, exploded by visual depth. Orbit it, hover a layer to isolate it, click to pin it.</p>
<ul class="ex-facts">
<li><b>0</b><span>lines of code added to the card</span></li>
<li><b>1:1</b><span>original styles restored on reassembly</span></li>
<li><b>3D</b><span>native preserve-3d, no DOM copies</span></li>
</ul>
<p class="ex-keys"><kbd>Enter</kbd> explode · <kbd>←</kbd><kbd>→</kbd><kbd>↑</kbd><kbd>↓</kbd> orbit · <kbd>+</kbd><kbd>−</kbd> spacing · <kbd>Esc</kbd></p>
</div>
<mv-exploded class="ex-view" controls exploded aria-label="Booking card in exploded view">
<article class="ex-card" data-mv-layer="Card">
<div class="ex-media" data-mv-layer="Media">
<svg viewBox="0 0 340 120" preserveAspectRatio="none" aria-hidden="true">
<path d="M0 120 L0 70 L60 22 L96 52 L142 8 L204 64 L240 40 L300 86 L340 60 L340 120 Z" fill="#6d86b8"/>
<path d="M142 8 L128 22 L138 20 L146 30 L154 18 L164 26 Z" fill="#fff"/>
<path d="M0 120 L0 92 L70 60 L130 96 L190 70 L260 100 L340 80 L340 120 Z" fill="#3f5f8f"/>
<path d="M0 120 L0 108 L90 92 L180 110 L270 96 L340 106 L340 120 Z" fill="#2b4169"/>
</svg>
<span class="ex-badge" data-mv-layer="Badge">Guest favorite</span>
<button class="ex-fav" type="button" aria-label="Add to favorites" data-mv-layer="Favorite">
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 21s-7.5-4.6-9.6-9.2C.9 8.4 3 4.5 6.8 4.5c2.1 0 3.6 1.1 5.2 3 1.6-1.9 3.1-3 5.2-3 3.8 0 5.9 3.9 4.4 7.3C19.5 16.4 12 21 12 21z"/></svg>
</button>
</div>
<div class="ex-body">
<div class="ex-host"><span class="ex-avatar" data-mv-layer="Host">MC</span><small>Maya, host since 2019</small></div>
<h3>Arolla Chalet</h3>
<p class="ex-meta">Zermatt · 6 guests · 3 bedrooms</p>
<div class="ex-tags" data-mv-layer="Amenities"><span>Sauna</span><span>Matterhorn view</span><span>Ski-in/ski-out</span></div>
<div class="ex-foot">
<div class="ex-price"><b>$460</b> / night</div>
<a class="mv-button" href="#" data-mv-layer="Primary action">Book</a>
</div>
</div>
</article>
</mv-exploded>
</div>API
Attributes
| Name | Typ | Default | Description |
|---|---|---|---|
exploded | boolean | Exploded state (reflected; setting it on load animates the opening). | |
trigger | toggle | hover | scroll | manual | toggle | toggle: keyboard, toolbar or API; hover: explodes on hover/focus; scroll: progress tied to scrolling (20 → 50% of the way through the viewport). |
gap | number (px) | 62 | Z spacing between two visible floors. |
depth | visual | dom | visual | visual: only elements that paint (background, border, shadow, text, media) add a floor; dom: one floor per nesting level. |
max-depth | number | 10 | Maximum number of floors (deeper elements stay on the last one). |
max-layers | number | 600 | Performance safeguard. |
tilt / spin | number (deg) | 54 / -32 | Exploded pose: tilt (rotateX) and spin (rotateZ). |
scale | number | 0.84 | Scales the assembly down once exploded (so it stays in frame). |
labels | auto | authored | none | auto | Labels: those from data-mv-layer, otherwise (auto) the largest plane on each floor with its tag.class. |
controls | boolean | Built-in toolbar (Explode/Assemble, Reset view). | |
data-mv-layer (descendant) | string | Layer name shown in a callout with a leader line. | |
data-mv-depth (descendant) | number | Forces how many floors this element adds (0 = stays on its parent’s plane). |
Properties
| Name | Typ | Description |
|---|---|---|
stats | { layers, levels } | Number of planes and floors in the current view. |
Methods
| Name | Description |
|---|---|
explode() / assemble() / toggle(force?) | Programmatic control. |
resetView() | Returns to the default pose after orbiting. |
Events
| Name | Description |
|---|---|
mv-explode / mv-assemble | State change. detail: { layers, levels }. |
mv-layer-hover | A plane is hovered. detail: { element, level }. |
CSS classes
| Name | Description |
|---|---|
mv-exploded-hud / -leaders / -callout / -tip | Annotation layer (aria-hidden): SVG leader lines, callouts, tooltip for the hovered plane. |
mv-exploded-toolbar / -btn / -hint | Toolbar (controls attribute). |
[data-mv-exploded-layer|leaf|ghost|clip|hover|pinned] | Temporary markers set on planes during the exploded view (removed on reassembly). |
CSS variables
| Name | Default | Description |
|---|---|---|
--mv-exploded-color | var(--mv-accent) | Wireframe, hover and leader lines. |
--mv-exploded-perspective | 1800px | Scene perspective. |
--mv-exploded-progress | 0 → 1 while exploding (read-only, usable in CSS). |
Accessibility
The host is focusable (role=group, aria-roledescription “exploded view”, aria-keyshortcuts): Enter/Space explodes or assembles, arrows orbit (Shift = faster), +/− adjust the spacing, Home resets, Escape unpins then assembles. The state is announced in a live region. While inspecting, clicks inside the interface are intercepted (you inspect, you don’t activate); the content stays readable by screen readers. Annotations are aria-hidden, the toolbar is accessible. Reduced motion: no springs or per-floor offsets, the pose applies instantly.