Anticode Open builder

The ease check: why CSS default ease timing marks an untuned interface

The ease check fails a page whose CSS transitions name the keyword ease, the browser's general-purpose timing curve. It's one of the Critic's quieter checks: it doesn't block publishing, and visitors can't name what's wrong. But motion on the default curve is a sign nobody tuned the interface, and the fix is a single line: define one curve for the site and use it everywhere.

Updated · By the Anticode team

What the default curve is, and why it feels off

A timing function decides how a change is spread over its duration: whether a button's colour shift starts fast and settles, or creeps in and snaps at the end. CSS default ease timing is a fixed curve that starts a little slowly, speeds up through the middle and slows at the end. It's a reasonable average, which is the problem. Interface motion feels responsive when it reacts at once and then eases into place, because that's how a physical object behaves when you push it. A curve that hesitates first makes hovers and menus feel slightly late, and when every transition on a page uses it, the whole site has the same faintly generic rhythm. The easing curves guide explains curves in more depth.

What the check matches

The Critic reads the page's stylesheet and looks for a transition declaration that contains the word ease standing on its own. It's a text rule, so its reach is exact:

What passes and what fails
In the stylesheetResult
transition: color .2s easeFails
transition-timing-function: easeFails
transition: color .2s ease-out (or ease-in, ease-in-out)Passes: the named variants aren't the bare keyword
transition: color .2s cubic-bezier(.2, 0, 0, 1)Passes
transition: color .2s (no curve named)Passes, although the browser then uses ease anyway
animation: pop 1s easePasses: animations aren't checked

Those last two rows are the check's blind spots. A transition with no curve still runs on the default, and keyframe animations are outside the rule, so passing means the stylesheet doesn't ask for ease by name in a transition, not that every movement is tuned.

The curves Anticode's design systems use

Every design-engine page defines its motion once, as variables at the top of the stylesheet, and every transition refers to them. That's what makes the check pass, and it's the pattern worth copying:

Interface curve
cubic-bezier(.2, 0, 0, 1): it leaves at full speed and spends most of its time settling, so hovers and focus changes feel immediate. Paired with a 150 millisecond duration.
Entrance curve
cubic-bezier(.16, 1, .3, 1): a long, soft landing as the page loads, over 700 milliseconds for the hero text and a little longer for its photo.
Spring
cubic-bezier(.34, 1.56, .64, 1): Playful only. The curve goes past its end point and returns, so the hero's shapes land with a small bounce.
Press
Brutalist's buttons move into the page on hover in a little over a tenth of a second, on the interface curve.

All of it switches off for visitors who've asked their device for reduced motion; see the prefers-reduced-motion guide.

Fixing a failure

  1. Define one curve as a custom property, for example --ease: cubic-bezier(.2, 0, 0, 1).
  2. Replace every ease in transitions with var(--ease).
  3. Keep durations short for small changes: colour and opacity in about 150 milliseconds, larger movements a little longer. See UI animation duration.
  4. Name a curve in transitions that had none, so they stop falling back to the default silently.

On a design-engine page you'll rarely see this check fail, because the stylesheet is generated with the variables above and the code editor doesn't keep CSS changes beyond colour tokens. It's most useful as a rule for your own projects and for anything exported and edited afterwards.

Limits

  • Reported, not enforced. The design gate doesn't include this check, so a failure never stops publishing.
  • Keyword, not feel. It can't judge whether a custom curve is any good; a badly chosen cubic-bezier passes.
  • Animations and implied defaults aren't covered, as shown above.
  • Pages only. Model-written apps are checked by their own gates, not by this lint rule.

Questions people ask

Does ease-in-out fail the check?

No. Only the bare keyword ease fails. Whether ease-in-out suits interface motion is another matter; it starts slowly too.

Is linear timing better than ease?

For most interface changes, no. Linear motion looks mechanical. A curve that starts fast and settles reads as most natural.

Why doesn't the check catch transitions with no curve named?

It reads what the stylesheet says rather than working out what the browser will do. A transition without a timing function still runs on the default curve, so name one explicitly even though the check would pass without it.

Will the ease check stop me publishing?

No. It's shown in the Report tab only.