Skip to content

Repository files navigation

overlay-morph

One overlay, three layouts. A record panel that morphs between slideover, modal and fullscreen with the View Transitions API — the entire component tree swaps, and the browser animates the difference.

Live demo

This is a technique demo, not a package. The interesting part is the CSS: src/styles/morph.css contains every recipe, with the reasoning next to each rule.

The techniques

  • Crisp text while the panel resizes. View-transition snapshots are bitmaps; by default the browser stretches the old and new images into the interpolating box and cross-fades them, so text warps and smears. The fix: natural-size snapshots, the group box as a clipping reveal window, and no cross-fade on content-identical pairs. The precondition is that the content column has the same width in every layout. Use the break the fix toggle in the demo to compare against the default.
  • Nested groups. view-transition-group: contain + ::view-transition-group-children (Chrome 140+) make the panel clip its named descendants instead of leaking them into the root transition. Older engines ignore the rules and still morph.
  • Typed, per-direction retiming. Every switch passes a type (om-slideover-to-modal, …), so :active-view-transition-type() can retime one morph family without touching any other view transition on the page — morphs into fullscreen glide on a decelerate, everything else springs, with a settle-pulse keyframe supplying the bounce.
  • The snapshot lock. While a morph runs, an om-vt-lock class on <html> force-disables the overlay shells' own CSS transitions — otherwise the "new" snapshot captures a panel mid-animation.
  • Staged aside. The activity column is rendered just beyond the slideover's edge with real geometry, so morphing to the split layouts reveals it instead of fading in a snapshot that was never captured.
  • Docked closes without <Transition>. Vue's rAF-gated leave keeps the old panel in the DOM while snapshots are taken; a duplicate view-transition-name silently aborts the whole morph. The docked panel collapses via a raw CSS width transition instead.

Falls back gracefully: without document.startViewTransition (or with prefers-reduced-motion) every switch is an instant swap.

Run it

pnpm install
pnpm dev

License

MIT

About

One overlay, three layouts — morphing between slideover, modal and fullscreen with the View Transitions API

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages