Skip to main content

Search rules

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

interactionsEmil Kowalski

Scale Pressable Elements on :active

SHOULD

SHOULD: Answer every press instantly with `transform: scale(0.97)` on `:active` and `transition: transform 160ms ease-out`. Stay inside 0.95–0.98 (0.85 reads as broken), and apply it to any pressable element — cards, icon buttons, list rows — not only `<button>`.

Confirm a press with transform: scale(0.97) and a 160ms ease-out transition

.pressable { transition: transform 160ms ease-out; }
.pressable:active { transform: scale(0.97); } /* Tailwind: active:scale-[0.97] */

Bad

Good

Why it matters

A press is the one moment the interface can answer instantly, before any network call resolves. Without it the user has no evidence the pointer-down landed, so on a slow action they press again — the classic double-submit. `transform: scale(0.97)` with `transition: transform 160ms ease-out` is the whole fix: compositor-only, cheap, and the range that reads as pressed is narrow (0.95–0.98) — 0.85 collapses the control and reads as broken.

It is also why `scale()` is the right property rather than a size change: `scale()` scales children too, so the icon and the label go down with the surface, which is exactly the physical model of a button being pushed. This applies to any pressable element — cards, icon buttons, list rows — not just things tagged `<button>`.

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.