A transition interpolates supported property values when they change. A transform changes visual geometry without changing the element's normal-flow allocation.
CSS transitions and transforms: animate a specific visual property
How the rule works
A receipt action can shift a few pixels on hover, but its focus state must remain equally clear for keyboard users. Transition only transform rather than all properties, so later color or outline changes do not start unexpected motion. A transform can create a stacking context and move painted content over neighbors; test the full toolbar when buttons are close together. Motion should not become the only indication that an action is available. If a press state matters, express it with a visible label or state as well.
.receipt-action { transform: translateY(0); transition: transform 140ms ease-out; }
.receipt-action:hover { transform: translateY(-2px); }
.receipt-action:focus-visible { outline: 3px solid #205c8a; outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
.receipt-action { transition: none; transform: none; }
}Cost and verification
Transform animation often avoids layout recalculation, but it can still use compositor memory and trigger paint depending on the element. Measure a real page with many actions before calling the effect free. Test reduced motion, touch input, keyboard focus, and overlap at high zoom. The sample's two-pixel movement is decorative; removing it does not change access to the action.
Common Mistakes
- Do not transition all properties without reviewing future state changes.
- Do not assume transforms change surrounding layout space.
- Do not hide a focus outline behind motion styling.
Connected lessons
- CSS Interaction and Accessibility
- CSS reduced motion: remove nonessential movement at the source
- CSS stacking contexts: debug overlays without arbitrary z-index inflation
- CSS focus-visible: keep keyboard location unmistakable
Further rendering decisions
- CSS will-change: reserve a rendering hint for measured trouble
- CSS transform-origin: move a visual pivot without moving the layout box
Related behavior decisions
- CSS @starting-style: define an element's entry state
- CSS discrete transitions: keep a closing panel visible long enough to fade
