box-shadow paints one or more blurred copies of an element's border box behind it. Each layer is an X offset, a Y offset, an optional blur, an optional spread, and a color — comma-separated when you stack them. This page is the reference: what each value does, what real sites ship, and copy-ready starting points you can tune in the generator below.
The shadow silhouette comes from the element's own border box, so border-radius on the same element rounds the shadow too. A shadow with no offset and no spread sits entirely behind the element — only the blur peeks out around the edges, which is why 0 0 with a visible color reads as a soft halo rather than depth.
Full layer syntax
box-shadow: offset-x offset-y blur-radius spread-radius color;Inset (draws inside the border box)
box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.15);Blur and spread are optional — drop them and the layer still parses, because color is unambiguous at the end while a bare length could be misread. Writing color last (or using a color function like rgba()) keeps the parser from treating a color keyword as a length.
| Value | What it does | Starting point |
|---|---|---|
| offset-x | Moves the shadow right (positive) or left (negative) from the border box. | 0 — production CSS pins X at zero almost universally |
| offset-y | Moves the shadow down (positive) or up (negative). | 0 to −4 px; down a little, or straight down |
| blur-radius | Feathers the edge outward from the silhouette. 0 keeps a hard edge. | Single digits for cards; 0 for focus rings |
| spread-radius | Grows (positive) or shrinks (negative) the silhouette before blurring. Box-shadow only. | 0, or −4 to −8 px to tuck wide blurs under a card |
| color | Any CSS color. With alpha it composites over what sits behind it. | rgba(0,0,0,0.08) to rgba(0,0,0,0.3) |
| inset | Keyword before the lengths; flips the shadow inside the border box. | Pressed buttons, input wells, the dark half of soft UI |
The six parts of a box-shadow layer, with practical starting values.
Each preview below applies exactly the declaration shown — the copy button writes that same string. Load any of them into the generator underneath to retune offsets, blur, and alpha live.
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06),
0 8px 24px -6px rgba(0, 0, 0, 0.12);box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1),
0 4px 12px -2px rgba(0, 0, 0, 0.12);box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.15);box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px rgba(217, 122, 63, 0.55);Layers are comma-separated and the first one paints on top. The pairing that reads as real depth is a tight contact shadow close to the surface plus a wide, faint ambient layer below it — two layers with different offsets, blurs, and alphas, not one thick dark smear.
Measured against the shipped CSS of the top 1,000 sites, most production shadows stay on a single layer with a zero X offset, a small or zero Y offset, single-digit blur, and a low-alpha neutral color. The stacks that do exist are usually framework tokens rather than art direction.
box-shadow traces the rectangle of the border box (rounded by border-radius) and supports spread and inset. text-shadow traces the outline of every glyph and accepts only X, Y, blur, and color. The third option, filter: drop-shadow(), traces the alpha shape of an image or an SVG — useful for icons and cut-outs, but without spread or inset, and as a filter it re-rasterizes the element whenever it or its shadow changes.
It draws one or more blurred copies of the element's border box behind it. Each layer has an X offset, a Y offset, an optional blur, an optional spread, and a color; the keyword inset draws the layer inside the border box instead of behind it.
The usual causes: a parent with overflow: hidden clips it, the color has no visible alpha (or matches the background), or another element paints over it. Give the layer a visible offset like 0 8px with blur 16 and a mid alpha first — if it appears, the layout was fine and the values were the problem.
Yes. Put the inset keyword before the lengths — box-shadow: inset 0 2px 6px rgba(0,0,0,0.15) — to draw the shadow inside the border box for recessed wells, pressed buttons, and soft-UI shading. Layers in one declaration can mix inset and outer freely.
box-shadow traces the element's border box, honors border-radius, and supports spread and inset. text-shadow traces each glyph's outline and takes only X offset, Y offset, blur, and color. Both accept comma-separated layers with the first layer painted on top.
No. box-shadow is unprefixed in every current browser, so clean standard CSS is enough. Old -webkit-box-shadow declarations still work but are unnecessary in new code.