open-slide

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:

SurfaceForwardBackward
--osd-dir1-1
data-osd-dirforwardbackward

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)',
  },
};

On this page