How box-shadow works
box-shadow paints a shadow around an element's border box. It follows border-radius, takes no space in the layout, and needs at least two values: how far to move it horizontally and vertically.
The syntax
box-shadow: [inset] <offset-x> <offset-y> [<blur>] [<spread>] [<color>];
| Value | Meaning | Default |
|---|---|---|
inset | Draw the shadow inside the box, like a pressed-in area | Outside |
| offset-x | Positive moves right, negative left | Required |
| offset-y | Positive moves down, negative up | Required |
| blur | How soft the edge is; cannot be negative | 0 (a hard edge) |
| spread | Grows (positive) or shrinks (negative) the shadow | 0 |
| color | Any color; a semi-transparent black usually looks best | The text color |
The number of lengths decides their meaning: two are the offsets, three add blur, four add spread. Try it:
Try 0 0 0 4px #f59e0b (a ring), inset 0 0 12px #2563eb, and -8px -8px 0 #16a34a.
Spread: rings and one-sided shadows
Spread changes the shadow's size before blurring. Two patterns come out of it:
- A ring: no offset, no blur, only spread. Unlike a border, it does not change the element's size, so it is a good focus indicator (
:focus-visible { box-shadow: 0 0 0 3px #2563eb; }). - A ring with a gap: stack a white spread under a colored, larger one.
- One side only: move the shadow down and shrink it with a negative spread, so it only peeks out at the bottom.
Layered shadows for realistic depth
Real shadows have a dark, sharp part close to the object and a soft, faint part further away. Two or three layers imitate that far better than one large blur:
The first shadow in the list is painted on top. Keep shadow colors semi-transparent black or a dark tint of the background, never pure gray, so they darken whatever is underneath.
Inset shadows
inset draws the shadow inside the padding box, as if the surface were pressed in. It suits text inputs, wells and pressed buttons:
input {
box-shadow: inset 0 1px 3px rgb(0 0 0 / 20%);
}
button:active {
box-shadow: inset 0 3px 6px rgb(0 0 0 / 30%);
}
An inset shadow is drawn above the background but below the content. Shadows that follow letter shapes instead of the box are text-shadow.
Common mistakes
- Pure black, fully opaque shadows. They look like a dark outline. Use 10% to 30% alpha.
- One huge blur for depth. Layer a small sharp shadow with a large soft one.
- A shadow cut off at the edge. An ancestor with
overflow: hiddenclips it; add padding to the ancestor or move the overflow rule. - Negative blur. It is invalid and the whole declaration is ignored.
- Animating
box-shadowon many elements. It repaints every frame. For heavy pages, animate theopacityof a pseudo-element that carries the bigger shadow instead.
Frequently Asked Questions
What is the box-shadow syntax?
box-shadow: offset-x offset-y blur spread color;, for example box-shadow: 0 4px 12px 0 rgb(0 0 0 / 15%);. Only the two offsets are required; add inset to draw the shadow inside the box.
What does spread do in box-shadow?
It grows (positive) or shrinks (negative) the shadow before it is blurred. A shadow with no offset, no blur and a spread of 3px is a solid 3px ring around the element.
How do I put a shadow only on the bottom?
Offset it down and pull it in with a negative spread so the sides disappear: box-shadow: 0 8px 6px -6px rgb(0 0 0 / 40%);.
Does box-shadow affect layout?
No. A shadow takes no space and does not move other elements, which is why it is a good way to add a focus ring or a hover lift without layout shift. It can be clipped by an ancestor's overflow: hidden.
Can I have multiple box shadows?
Yes, separate them with commas. The first shadow is drawn on top. Layering a small sharp shadow with a large soft one looks more natural than one big shadow.