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.
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.
| State | Property | Token | Now |
|---|---|---|---|
| initial | opacity | literal | 0 |
| scale | {scale.enter} | 0.96 | |
| y | {distance.md} | 15 | |
| animate | opacity | literal | 1 |
| scale | literal | 1 | |
| y | literal | 0 | |
| exit | opacity | literal | 0 |
| scale | {scale.enter} | 0.96 | |
| y | {distance.md} | 15 | |
| transition | Movement (spring) | {spring.default} | stiffness 511 · damping 40 |
| transition | Fade duration | {duration.base} | 188ms |
| transition | Fade easing | {easing.enter} | cubic-bezier(0, 0, 0, 1) |
| transition | Exit duration | {duration.fast} | 132ms |
| transition | Exit easing | {easing.exit} | cubic-bezier(0.3, 0, 1, 1) |
Tokens used
spring.default stiffness 511 · damping 40duration.base 188mseasing.enter cubic-bezier(0, 0, 0, 1)duration.fast 132mseasing.exit cubic-bezier(0.3, 0, 1, 1)scale.enter 0.96distance.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.