Skip to main content

Search rules

Search all UI Guides rules by name, category, or source

animationsanimate-text

A Hard Cut Is steps(), Not a Fast Fade

MUST

MUST: Any effect whose identity is discreteness — typewriter, per-word hard cut, blinking caret — must use steps(1, end), not an eased opacity ramp. A fade puts every unit in a half-present state for its whole duration, so at a normal stagger several are ghosting at once and the line smears instead of typing. The rhythm belongs to the stagger; the duration is only a gate.

A typewriter or word-by-word cut needs a stepped easing — a 240ms opacity ramp per character is not typing, it is a smear resolving

// bad — 240ms ramp, ~5 glyphs half-present at a 46ms stagger
animation: fade 240ms ease-out both;
// good — struck or absent, never in between
animation: type 240ms steps(1, end) both;
animationDelay: `${i * 46}ms`;

Bad

Good

Why it matters

Two of the catalog's 24 effects reach for `steps(1, end)`, and both are effects whose entire identity is discreteness. A typewriter is a machine setting one glyph at a time: the character is struck or it is not, and there is no state in between. Build it from a 240ms opacity ramp at a 46ms stagger and roughly five characters are half-present at any moment, so the line reads as a grey smear resolving rather than as typing — the effect you asked for is the one thing you cannot see.

`steps(1, end)` collapses the whole duration into a single transition at its end, which is also why a stepped effect survives being retimed: the RHYTHM lives entirely in the stagger and the duration is just a gate. The same argument covers `shared-axis-y`, a staircase of per-word hard swaps — ease it and a deliberate edit becomes a cross-dissolve. This is the one place in this corpus where an instant transition is the craft rather than the shortcut, and it is not in tension with animations-emil-no-ease-in: that rule chooses among CONTINUOUS curves and has nothing to say about a transition with no in-between. A stepped reveal is still motion, so `prefers-reduced-motion` should still land the whole string at once.

Built by Gleb Stroganov, design engineer at Evil Martians.

The rules come from other people's skills and guidelines — Vercel, Rauno Freiberg, @Ibelick, impeccable, Emil Kowalski, Tailwind, RAMS — each one credited on the Sources page. The work here is extraction and wiring: every rule is pulled into one corpus, given a good and a bad example you can operate, a MUST/SHOULD/NEVER rule an agent can paste, and a link back to where it came from.