Skip to content

Search pages

Jump to any page on the site.

Overlay

The backdrop fades in. The panel scales up and rises.

Live demo

The preset here changes the whole site. Slow motion and reduced motion change this stage only.

Frame by frame

Every frame of the movement, on top of each other. Wide gaps are fast. Ghosts past the dashed outline are overshoot. It updates with the preset.

24 frames383 ms · drawn 2.7×
24 frames at 60 fps. Settles in 383 ms, overshoots 0.3%.

When to use

Dialogs and alert dialogs: a panel that opens over the middle of the page. The backdrop fades, and the panel scales up from scale.enter and rises distance.md. The exit is a faster tween with no overshoot, so closing never feels slower than opening.

Move focus into the panel as soon as it opens. Do not wait for the animation. For a panel that comes from an edge, use drawer. For a list of actions under a button, use menu.

Recipe

Dialogs and alert dialogs. The backdrop fades in. The panel scales up from scale.enter and rises distance.md. Exit reverses, faster.

States of the overlay recipe
StatePropertyTokenNow
initialopacityliteral0
scale{scale.enter}0.96
y{distance.md}15
animateopacityliteral1
scaleliteral1
yliteral0
exitopacityliteral0
scale{scale.enter}0.96
y{distance.md}15
transitionMovement (spring){spring.default}stiffness 511 · damping 40
transitionFade duration{duration.base}188ms
transitionFade easing{easing.enter}cubic-bezier(0, 0, 0, 1)
transitionExit duration{duration.fast}132ms
transitionExit easing{easing.exit}cubic-bezier(0.3, 0, 1, 1)

Tokens used

  • spring.default stiffness 511 · damping 40
  • duration.base 188ms
  • easing.enter cubic-bezier(0, 0, 0, 1)
  • duration.fast 132ms
  • easing.exit cubic-bezier(0.3, 0, 1, 1)
  • scale.enter 0.96
  • distance.md 15px

Code

/* overlay: Dialogs and alert dialogs. The backdrop fades in. The panel scales up from scale.enter and rises distance.md. Exit reverses, faster.
   Use: .motif-overlay-backdrop and .motif-overlay-panel. They enter when mounted.
   To exit, set data-state="closed" and unmount after the transition (e.g. Radix forceMount).
   To grow it out of the clicked element, set --motif-origin on the panel (e.g. "40px 120px"). */
.motif-overlay-backdrop {
  transition: opacity var(--motif-duration-base) var(--motif-ease-enter);
}
@starting-style {
  .motif-overlay-backdrop {
    opacity: 0;
  }
}
.motif-overlay-backdrop[data-state="closed"] {
  opacity: 0;
  transition: opacity var(--motif-duration-fast) var(--motif-ease-exit);
}
.motif-overlay-panel {
  transform-origin: var(--motif-origin, center);
  transition:
    opacity var(--motif-duration-base) var(--motif-ease-enter),
    transform var(--motif-spring-default-duration) var(--motif-spring-default),
    filter var(--motif-duration-base) var(--motif-ease-enter),
    clip-path var(--motif-spring-default-duration) var(--motif-spring-default);
}
@starting-style {
  .motif-overlay-panel {
    opacity: 0;
    transform: translateY(var(--motif-distance-md)) scale(var(--motif-scale-enter));
    filter: none;
    clip-path: none;
  }
}
.motif-overlay-panel[data-state="closed"] {
  opacity: 0;
  transform: translateY(var(--motif-distance-md)) scale(var(--motif-scale-enter));
  filter: none;
  clip-path: none;
  transition:
    opacity var(--motif-duration-fast) var(--motif-ease-exit),
    transform var(--motif-duration-fast) var(--motif-ease-exit),
    filter var(--motif-duration-fast) var(--motif-ease-exit),
    clip-path var(--motif-duration-fast) var(--motif-ease-exit);
}

/* Reduced motion: the variable overrides at the end of motif.css set
   travel to 0, scale to 1, and blur to 0, so this recipe needs no extra rule. */

Reduced motion

  • No rise and no scale. The backdrop and panel fade at duration.fast. Focus still moves into the dialog at once.
  • Fades take 132ms (duration.fast), so the state change stays visible.
  • Turn on the Reduced motion box under the demo to preview it, or set your system to reduce motion.