Easing: where the speed goes
Once something should move, the next decision is not how long it moves but where the speed goes. Easing is the curve that distributes motion over time, and Emil Kowalski calls it, in 7 Practical Animation Tips, “the most important part of any animation.”
Ease-out is the default#
His justification is a demonstration. Two dropdowns open over an identical 300ms; the left uses ease-in, which starts slow, the right ease-out, which starts fast. The left feels slower, and nothing else differs. “That’s the difference easing makes.”
Ease-out accelerates at the beginning, and that early speed reads as responsiveness, so he uses it for anything entering or leaving the screen; in Train Your Judgement he adds that the gentle deceleration into place is what makes an entering toast elegant. Ease-in speeds up at the end, and “this easing is just not made for UI animations”; his skill file makes it a rule. Ease-in-out is for the third case: in Good vs Great Animations something already on screen that moves should accelerate and decelerate “just like a car.” Even so, default to ease-out.
He collapsed those judgements into a flowchart, shown in Agents with Taste and in his post on building the course, strict on purpose: “It just follows the flowchart and picks the right easing according to my philosophy.” Plain ease survives as an exception for simple hover changes such as a background color.
Is the element entering or exiting the viewport?
├── Yes → ease-out
└── No
├── Is it moving/morphing on screen?
│ └── Yes → ease-in-out
└── Is it a hover change?
├── Yes → ease
└── Is it constant motion?
├── Yes → linear
└── Default → ease-outKeywords are too weak#
The second thing Emil insists on: “The built-in easing curves in CSS are usually not strong enough, which is why I almost never use them.” Custom curves feel more energetic, and he points readers at easings.co and easing.dev. In the explorer below, start with the ease-out preset, then push the handles so the curve rises far more steeply at the start. Distance and time do not change; only the distribution does.
Named curves and tokens#
Easing Graphs (easing.dev), by Alex Vanderzon and Lochie Axon, lists 28 curves with their cubic-bezier values. Out Quint is cubic-bezier(0.23, 1, 0.32, 1), the exact value Emil ships as --ease-out. In Out Quart, cubic-bezier(0.77, 0, 0.175, 1), is his --ease-in-out and the curve behind his clip-path reveals. Snappy Out, cubic-bezier(0.19, 1, 0.22, 1), is identical to Out Expo. Anticipate, cubic-bezier(1, -0.4, 0.35, 0.95), dips below zero before it travels; Overshoot Out, cubic-bezier(0.175, 0.885, 0.32, 1.275), passes its target and comes back; both are by Lochie Axon. The keyword ease is In Out Base, cubic-bezier(0.25, 0.1, 0.25, 1). Emil’s third token, --ease-drawer, came from the Ionic Framework because it closely matches iOS.
--ease-out: cubic-bezier(0.23, 1, 0.32, 1);--ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);--ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);He also keeps a private set. His course ships 18 custom easings “that I use in my own projects,” and the first six are visible on the page about building the course. The names matter more than the numbers: a named curve gets reused, and reuse is what makes a product cohesive.
:root {--ease-breeze: cubic-bezier(.55, .085, .68, .53);--ease-silk: cubic-bezier(.52, .062, .64, .21);--ease-swift: cubic-bezier(.86, .04, .67, .24);--ease-nova: cubic-bezier(.73, .065, .82, .08);--ease-crisp: cubic-bezier(.92, .06, .77, .045);--ease-glide: cubic-bezier(.58, .06, .95, .32);In Great Animations he chooses against his own default: Sonner is a bit slower than usual and uses ease rather than ease-out, because that felt more elegant and matched the toast design, the page design, even the name. So: ease-out unless the element is already on screen, a named custom curve instead of a keyword, and the choice written down as a token.