Easing for a UI panel or card: curve, duration and what to avoid
Use land for a UI panel or card, over 0.22 to 0.5 s. land reaches 50% of its travel at 14% of the time and 90% at 49%. Avoid scale or overshoot on a panel.
Demo
land
linear
The same move with land and with linear. If your system asks for reduced motion, nothing plays and the final state shows.
Ease and duration
- Ease
- landpeak speed 4.8x the average
- Duration
- 0.22 to 0.5 s
- Halfway at
- 14% of the time90% of the travel at 49%
What to avoid
Scale or overshoot on a panel. A copied product panel only fades in 220 ms with a 0.8vh rise.
Code
@keyframes rise {
from { opacity: 0; translate: 0 0.8vh; }
to { opacity: 1; translate: 0 0; }
}
.target {
animation: rise 220ms cubic-bezier(0.12, 0.576, 0.25, 1) both;
}el.animate(
[{ opacity: '0', translate: '0 0.8vh' }, { opacity: '1', translate: '0 0' }],
{ duration: 220, easing: 'cubic-bezier(0.12, 0.576, 0.25, 1)', fill: 'both' },
);animation-timing-function: linear(0, 0.1162, 0.2217, 0.3146, 0.3951, 0.4645, 0.5245, 0.5766, 0.6223, 0.6625, 0.6981, 0.7298, 0.7582, 0.7836, 0.8066, 0.8273, 0.846, 0.863, 0.8784, 0.8924, 0.9051, 0.9166, 0.9271, 0.9366, 0.9452, 0.9529, 0.9599, 0.9662, 0.9718, 0.9768, 0.9812, 0.9851, 0.9884, 0.9913, 0.9937, 0.9957, 0.9973, 0.9985, 0.9994, 0.9998, 1);import { EASE } from '../../core/motion/presets.js';
el.animate(keyframes, { duration: 220, easing: EASE.land, fill: 'both' });Measured source
Measured on ChatGPT and Vercel Analytics clips at 30 fps, read off frames, plus or minus 33 ms. The numbers live in UI, imported from core/motion/presets.js.
| Preset | Value | Measured |
|---|---|---|
| Panel in | fade 220 ms, rise 0.8vh | A window fades in 0.10 to 0.23 s with at most 2 px of rise, no scale. |