Skip to main content

Search rules

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

animationsEmil Kowalski

Translate by Percentage, Not Pixels

SHOULD

SHOULD: Park off-screen elements with translate percentages, not hardcoded px: `translateY(100%)` resolves against the element's own height, so it stays correct when a toast wraps or a drawer gains a row. Add edge gaps with `calc(100% + 12px)` rather than a magic number.

Offset off-screen elements with translate percentages so the value stays correct at any size

.toast { transform: translateY(calc(100% + 12px)); } /* not translateY(300px) */
.toast[data-open] { transform: translateY(0); }

Bad

Good

Why it matters

A translate percentage resolves against the element itself, not its parent: translateY(100%) always moves it by exactly its own height, and translateX(-100%) by its own width. That is why a hardcoded translateY(300px) is a latent bug — it was measured against the content that existed the day it was written, and the moment a toast wraps to a second line or a drawer gains a row, the offset is wrong.

Too small and the "hidden" element peeks into view; too large and it flies in from further away than it should, stretching the perceived duration. Percentages are self-correcting, which is exactly how Sonner parks toasts and Vaul parks drawers. Add the gap to the edge with calc(100% + 12px) rather than baking it into a magic number.

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.