Reveal
Children fade and rise, one after another.
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
Lists, grids, and search results: groups of items that appear together. Each child fades in and rises distance.md, one after another. The stagger stops at stagger.cap children, so a long list does not keep the last item waiting.
Use it when content first appears, not on every scroll.
Recipe
Lists, grids, search results. Children fade in and rise distance.md, one after another, up to stagger.cap.
| State | Property | Token | Now |
|---|---|---|---|
| initial | opacity | literal | 0 |
| y | {distance.md} | 15 | |
| animate | opacity | literal | 1 |
| y | literal | 0 | |
| exit | opacity | literal | 0 |
| y | literal | 0 | |
| 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) |
| transition | Stagger delay | {stagger.list} | 32ms |
| transition | Stagger cap | {stagger.cap} | 8 |
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)stagger.list 32msstagger.cap 8distance.md 15px
Code
/* reveal: Lists, grids, search results. Children fade in and rise distance.md, one after another, up to stagger.cap.
Use: <ul class="motif-reveal">. Children enter when mounted. */
.motif-reveal > * {
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-reveal > * {
opacity: 0;
transform: translateY(var(--motif-distance-md));
filter: none;
clip-path: none;
}
}
.motif-reveal > * {
transition-delay: calc(var(--motif-stagger-step) * var(--motif-stagger-n, 0));
}
.motif-reveal > :nth-child(2) {
--motif-stagger-n: 1;
}
.motif-reveal > :nth-child(3) {
--motif-stagger-n: 2;
}
.motif-reveal > :nth-child(4) {
--motif-stagger-n: 3;
}
.motif-reveal > :nth-child(5) {
--motif-stagger-n: 4;
}
.motif-reveal > :nth-child(6) {
--motif-stagger-n: 5;
}
.motif-reveal > :nth-child(7) {
--motif-stagger-n: 6;
}
.motif-reveal > :nth-child(8) {
--motif-stagger-n: 7;
}
/* Children past stagger.cap (8) enter with the last staggered child. */
.motif-reveal > :nth-child(n + 9) {
--motif-stagger-n: 7;
}
/* 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 stagger. All children fade in together at duration.fast.
- 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.