Overview
Card hover-lift effect that combines transform: translateY with an expanding box-shadow radius so the card visibly rises from the surface. Three product contexts ship: dashboard metric tile, product-catalogue card with thumbnail, hero CTA panel with arrow.
When to use it
Reach for hover-lift on linkable cards (product grids, dashboard tiles, blog index entries). Skip it for dense list rows — the cumulative translateY noise becomes distracting. Skip it for touch-first contexts; without hover, the lift never reads, so save the design budget for touch-feedback patterns instead.
How it works
At rest the card has a tight box-shadow: 0 2px 4px rgba(0,0,0,0.08) suggesting it sits close to the surface. On :hover, transition to a wider, softer shadow like 0 12px 28px rgba(0,0,0,0.16) alongside a transform: translateY(-4px). The compound effect — shadow growing + element rising — sells the physics. Use a transition duration around 180–240ms with cubic-bezier(.2, .8, .2, 1) for the lift to feel material rather than abrupt. Always also handle :focus-visible with the same lift so keyboard users see the affordance.
Production gotchas
Animating box-shadow is more expensive than animating transform — both trigger paint on the shadow region. For high card counts, swap to a pre-baked dual-shadow approach: layer two box-shadows with different opacities and animate the second layer’s opacity instead of the radii. The translate must not push the card outside any clipping ancestor — check overflow: hidden parents. On macOS, the soft-shadow rendering treats blurs above ~30px as expensive on retina displays.
Accessibility
Cards used as links must be a real <a> element — not a div with onClick — so keyboard users can tab to them. The hover-lift must mirror under :focus-visible or you orphan keyboard users from the affordance. Under prefers-reduced-motion: reduce drop the translate and keep only the shadow change, or drop the animation entirely and use a subtle border change for the focused state.
References
Implementation depth
translateY should carry the lift while box-shadow carries the perceived elevation. Keeping those jobs separate lets the card feel deeper without changing layout or forcing neighboring content to reflow.
Hover depth also needs keyboard parity. Pair hover with focus-visible, make touch devices work without relying on hover, and reduce motion by keeping the elevated shadow but removing the moving lift.