SlideTransition
Per-page enter/exit animations and morph transitions.
The framework can run an enter/exit animation between every page change. There
is no default — pages snap unless you declare a SlideTransition. For
where to declare one and how precedence works, see
Transition; this page is the schema plus a
reusable set of examples.
prefers-reduced-motion: reduce is honored automatically — you don't write a
fallback.
Schema
SlideTransition
Prop
Type
TransitionPhase
Prop
Type
MorphTransition
Prop
Type
Background
The outgoing and incoming pages are stacked in one container painted with the
deck background (--osd-bg), incoming on top. Every page paints its own
background, so while the outgoing page stays opaque the incoming page fades in
over it and the container colour is never visible.
An exit that fades to opacity: 0 would expose the container before the enter
has covered it — a dip to black on any page whose background differs from
--osd-bg. The runtime therefore drops opacity from exit keyframes;
transform and filter still apply. Write the fade on enter and keep the
exit as a hold:
export const transition: SlideTransition = {
duration: 260,
exit: { keyframes: [{ opacity: 1 }, { opacity: 1 }] },
enter: { keyframes: [{ opacity: 0 }, { opacity: 1 }] },
};Set throughBackground: true when the dip is the point — a section break that
goes to black between two pages that share the deck background. Exit keyframes
then run exactly as written.
const breath: SlideTransition = {
duration: 460,
throughBackground: true,
exit: { duration: 180, keyframes: [{ opacity: 1 }, { opacity: 0 }] },
enter: { duration: 240, delay: 300, keyframes: [{ opacity: 0 }, { opacity: 1 }] },
};Direction hook
The framework writes two values on the transition wrapper so a single keyframe can mirror itself on backward navigation:
| Surface | Forward | Backward |
|---|---|---|
--osd-dir | 1 | -1 |
data-osd-dir | forward | backward |
Use --osd-dir inside calc():
{ transform: 'translateX(calc(var(--osd-dir, 1) * 8px))' },
{ transform: 'translateX(0)' },Most decks shouldn't mirror on backward navigation — reach for the direction hook only when the motion has a literal direction (a horizontal advance, a chapter sweep).
Morph
morph enables MorphElement matching: wrap
the same visual object on two pages with the same id and the runtime
animates it across the cut instead of fading it. Marked elements that exist on
only one of the two pages fade in or out automatically.
Use the object form when the morph needs its own timing:
export const transition: SlideTransition = {
duration: 900,
enter: { keyframes: [{ opacity: 0 }, { opacity: 1 }] },
exit: { keyframes: [{ opacity: 1 }, { opacity: 1 }] },
morph: {
duration: 900,
easing: 'cubic-bezier(0.22, 1, 0.36, 1)',
},
};