CSS Box Shadow: The Complete Guide

The box-shadow property has five values and one easy-to-miss keyword. Here's what each one actually controls.

The syntax

box-shadow: [inset] offset-x offset-y blur-radius spread-radius color;

Only offset-x, offset-y, and color are required — blur and spread default to 0 if omitted. A minimal usable shadow is just:

box-shadow: 2px 4px rgba(0, 0, 0, 0.25);

Each value, explained

  • offset-x — horizontal position. Positive pushes the shadow right, negative pushes it left.
  • offset-y — vertical position. Positive pushes the shadow down, negative pushes it up. Most natural-looking shadows use a positive offset-y and little or no offset-x, mimicking an overhead light source.
  • blur-radius — how soft the shadow's edge is. 0 gives a hard-edged silhouette; larger values spread the shadow into a soft gradient. Never negative.
  • spread-radius — grows or shrinks the shadow's shape before blurring is applied. Positive values make the shadow larger than the element in every direction; negative values shrink it — useful for tightening a shadow that a large blur radius has spread too far.
  • color — almost always a partially transparent black or a color matching the background, e.g. rgba(0, 0, 0, 0.25). A fully opaque shadow color looks like a flat shape, not a shadow.
  • inset — the one keyword in the property. Placed first, it flips the shadow from an outer drop shadow to an inner one that appears to recede into the surface — used for pressed buttons, input fields, and inset panels.

Layering multiple shadows

box-shadow accepts a comma-separated list, and every real-world "elevation" system (Material Design's included) uses two or three stacked shadows rather than one. A single large blurred shadow looks flat and artificial; combining a tight, low-opacity shadow with a larger, softer one reads as more physically plausible:

box-shadow:
  0 1px 2px rgba(0, 0, 0, 0.12),
  0 4px 12px rgba(0, 0, 0, 0.10);

The first line simulates a close, sharp contact shadow; the second simulates ambient light falloff.

Common patterns

  • Card elevation: small offset, moderate blur, low opacity — 0 2px 8px rgba(0,0,0,0.1).
  • Focus ring: zero blur, larger spread, brand color instead of black — 0 0 0 3px rgba(99,102,241,0.4) — a common accessible alternative to outline that respects border-radius.
  • Pressed / inset button: inset 0 2px 4px rgba(0,0,0,0.25).
  • Neumorphism (soft embossed UI): two shadows on opposite corners, one light and one dark, both low-contrast against the background — -6px -6px 12px rgba(255,255,255,0.7), 6px 6px 12px rgba(0,0,0,0.15).

Performance note

Large blur radii are more expensive to paint than small ones, and animating box-shadow directly (e.g. on hover) forces the browser to repaint rather than composite on the GPU. For a shadow that changes on hover, animating opacity on a separate pseudo-element with a fixed shadow is noticeably smoother than animating the box-shadow value itself.

Try it yourself

CSS Box Shadow Generator →