Home / Snippets / Animation & Motion /
Shadow grow
A card whose box-shadow intensifies on hover, creating a lift effect with no JavaScript.
Quick implementation
.shadow-grow {
box-shadow: 0 2px 8px oklch(0 0 0 / 0.2);
transition: box-shadow 0.3s ease;
}
.shadow-grow:hover {
box-shadow: 0 8px 24px oklch(0 0 0 / 0.4);
}
@media (prefers-reduced-motion: reduce) {
.shadow-grow { transition: none; }
}
Prompt this to your LLM
Includes role, constraints, two framework variants, and edge cases to handle.
You are a senior frontend engineer building a CSS interaction library.
Goal: A shadow grow hover effect — a card starts with a subtle box-shadow and it intensifies on hover to suggest elevation, using only CSS.
Technical constraints:
- Set box-shadow: 0 2px 8px oklch(0 0 0 / 0.2) as the resting state.
- On :hover, transition to box-shadow: 0 8px 24px oklch(0 0 0 / 0.4).
- Use transition: box-shadow 0.3s ease — not transition: all.
- Use oklch() with an alpha channel for shadow colors, not rgba() or hex.
- Include @media (prefers-reduced-motion: reduce) to remove the transition (the shadow still changes on hover, just instantly).
Framework variant (pick one):
A) Vanilla CSS — configurable via --shadow-rest and --shadow-hover custom properties.
B) React component — accept restShadow and hoverShadow as string props.
Edge cases to handle:
- box-shadow does not affect layout — it will not push sibling elements. Confirm this is intentional.
- Pair with a subtle translateY(-2px) on hover for a stronger lift illusion (add to the transition list).
- On dark backgrounds, use lower alpha values to avoid a muddy shadow halo — oklch(0 0 0 / 0.4) is a safe ceiling.
- Do not animate box-shadow with @keyframes if possible — transitions give smoother reverse-on-exit for free.
Return CSS.
Why this matters in 2026
Shadow grow is the subtlest way to signal that a card is interactive. It mimics real-world elevation — a raised object casts a deeper shadow — so users intuitively understand the card is clickable. Unlike border or color changes, a shadow change does not alter the card's dimensions or surrounding layout, making it safe for dense grid layouts where shifting elements cause visual jitter.
The logic
The resting box-shadow uses a small blur-radius (8px) and low alpha (0.2) to suggest grounding. The hover state grows the y-offset from 2px to 8px and the blur from 8px to 24px, while doubling the alpha to 0.4 — both changes simulate the card lifting off the page. transition: box-shadow 0.3s ease on the base state means CSS automatically reverses the transition on :not(:hover) without a separate rule.
Accessibility & performance
@media (prefers-reduced-motion: reduce) removes only the transition, so the shadow still switches between states on hover — the interaction is preserved without animation. box-shadow transitions are paint operations, slightly more expensive than transform-only changes, but well within budget for card-sized elements. Avoid animating box-shadow on large full-viewport elements or in tight loops with JavaScript-driven hover state updates.