Design

CSS box-shadow generator

Design CSS shadows with live preview. Tweak offset, blur, spread and color; stack multiple layers for realistic depth. Copy the code straight into your stylesheet.

Instant🔒In your browserNo signup
Live

Anatomy of box-shadow

The CSS syntax is box-shadow: x y blur spread color;:

  • X: horizontal offset. Positive = right. For realistic shadows almost always 0.
  • Y: vertical offset. Positive = down. Usually 4-20px to emulate top-down lighting.
  • Blur: shadow softness. Low values (0-4px) give brutalist hard shadows; high (20-50px) give modern soft ones.
  • Spread: how much the shadow expands before blur. Negative shrinks, positive enlarges. Almost always 0.
  • Color: ideally rgba with low opacity (4-15%). Pure black at 100% looks plastic.

The multi-shadow trick

The "premium" shadows you see on Stripe, Vercel or Linear aren't a single shadow: they're two or three stacked. One short and crisp close to the element (1-2px Y, low blur, medium opacity), and a long diffuse one further down (8-20px Y, high blur, low opacity). It mimics how real light casts both a direct and an indirect shadow.

box-shadow:
  0 1px 2px rgba(9, 9, 11, 0.06),
  0 4px 12px rgba(9, 9, 11, 0.08);

Inset: when to use it

An inset shadow goes inside the element and simulates reversed depth. Legit uses: pressed-state inputs, containers that look sunken into the page, active drop zones. Illegit use: every button (2010s skeuomorphism — it does not age well).

Shadows in dark mode

Shadows are far less visible on dark backgrounds: black on black is nearly invisible. Solutions:

  1. Light borders instead of shadows: border: 1px solid rgba(255,255,255,0.08).
  2. Higher opacity shadows (20-40% instead of 8-12%) with bigger blur.
  3. Colored shadows: in dark mode, a low-opacity shadow tinted with your brand color produces a "glow" rather than depth.

Performance: when it can tank your frame rate

Box-shadow is computed on the CPU (not GPU). Animating blur on 100 elements at once tanks the frame rate. If you need to animate shadows (e.g. on hover), use transform instead of changing blur, or use filter: drop-shadow() which is GPU-accelerated and respects transparent edges (useful for SVG and images with backgrounds).

Four shadows that work in any UI

  • Card subtle: 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04)
  • Card hover: 0 4px 12px rgba(0,0,0,0.08), 0 2px 4px rgba(0,0,0,0.05)
  • Modal / popover: 0 12px 32px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.06)
  • Floating button: 0 6px 20px rgba(0,0,0,0.15), 0 2px 6px rgba(0,0,0,0.08)

FAQ

What is inset?

Inner shadow: reversed depth. Useful for pressed inputs or drop zones.

Multi-shadow?

Yes: comma-separate. Stacking 2-3 produces the realistic Stripe-like effect.

Why does it look cheap?

Opacity too high, blur too low. Realistic ones use 4-12% alpha, 8-30px blur, slight downward offset.

Performance?

Box-shadow runs on CPU. To animate many elements, prefer transform or filter: drop-shadow.

Was this generator useful?