Transition hovers, don't scale
Give hovers 150–200ms, and save scale for one element.
Jakub Kreheljakub.krInstead of borders, I often prefer to use a subtle box-shadow that adds more depth to the element. For the hover state, it is the same box-shadow, just slightly darker.
From design-motion-principles, audit checklist and anti-checklist.
Instant, 150ms, 400ms
Hover or tap all three, then drag the slider.
InstantBad
transition: none150msGood
transition: background-color 150ms ease400msBad
transition: background-color 400ms ease.button {
transition:
background-color 150ms ease,
color 150ms ease,
border-color 150ms ease;
}
@media (hover: hover) and (pointer: fine) {
.button:hover { background: var(--accent); color: var(--accent-ink); }
}
Nine cards, one CTA
Hover or tap the cards, or press Sweep.
Scale on every cardBad
transition: all 300ms:hover { scale(1.05) }Only the CTA scalesGood
transition: box-shadow 150msCTA: scale(1.03).card {
box-shadow:
0 0 0 1px rgba(0, 0, 0, 0.06),
0 1px 2px -1px rgba(0, 0, 0, 0.06),
0 2px 4px 0 rgba(0, 0, 0, 0.04);
transition: box-shadow 150ms ease;
}
.card:hover {
box-shadow:
0 0 0 1px rgba(0, 0, 0, 0.08),
0 1px 2px -1px rgba(0, 0, 0, 0.08),
0 2px 4px 0 rgba(0, 0, 0, 0.06);
}
.cta { transition: transform 150ms var(--ease-out), background-color 150ms ease; }
.cta:hover { transform: scale(1.03); }
.cta:active { transform: scale(0.97); }
Why it matters, pros and cons
Why it matters
Instant hover reads as a glitch; 150–200ms as a response. Scale one thing only.
Pros
- Color and shadow transitions never block anyone.
- The grid stays still, so prices stay readable.
- The one scaled CTA gains weight.
Cons
- Past ~300ms a hover lags the cursor.
- Utility rows and icon buttons get no scale.
- Touch has no hover; never hide content behind it.