Bridge appearing content
Anything that appears or vanishes gets a short fade-and-scale bridge.
Emil Kowalskifind-animation-opportunitiesContent that swaps, appears, or vanishes instantly (conditional renders, route content, expanding sections) → fade/scale entrances from `scale(0.95–0.97)` + `opacity: 0`, `ease-out`, never `scale(0)`; `@starting-style` for entry without JS
Emil Kowalskifind-animation-opportunitiesList items added/removed with no bridge (and the list isn't high-frequency) → enter/exit transitions; CSS transitions, not keyframes, so rapid triggers retarget smoothly
From find-animation-opportunities and improve-animations.
A conditional render
Type in the box, then clear it.
Instant mountBad
Results appear here
{query && <Results/>}@starting-style entryGood
Results appear here
opacity + scale(0.96), 200ms ease-out
Accordion: snap vs. open
Open a question, then press Toggle rapidly.
display: none toggleBad
[hidden]Height + opacityGood
grid-template-rows 250ms, opacity 200ms, ease-out
List inserts and removals
Add and remove tasks, then try the live feed.
No transitionBad
No tasks
.map()Enter/exit transitionsGood
No tasks
220ms var(--ease-out).row {
display: grid;
grid-template-rows: 1fr;
transition: grid-template-rows 220ms var(--ease-out),
opacity 220ms var(--ease-out),
transform 220ms var(--ease-out);
}
@starting-style {
.row { grid-template-rows: 0fr; opacity: 0; transform: translateY(-4px); }
}
.row[data-leaving] {
grid-template-rows: 0fr; opacity: 0; transform: scale(0.98);
}
.row > .clip { min-height: 0; overflow: hidden; }
.list[data-high-frequency] .row { transition: none; }
Why it matters, pros and cons
Why it matters
Teleporting content makes the eye rescan. A 150–250ms bridge shows what moved.
Pros
- The user keeps their place.
@starting-styleneeds no JS.- Transitions retarget on rapid toggles.
Cons
- High-frequency lists turn motion into noise.
- Exits keep elements mounted until
transitionend. - Height transitions run layout every frame.