Toolmingo
Guides5 min read

CSS Box Shadow: Complete Guide with Examples

Learn how CSS box-shadow works, understand every parameter, see common shadow effects with code, and use a visual generator to build them without guessing.

The CSS box-shadow property is one of those rules you either remember exactly or look up every single time. The syntax has five parameters, two optional, one with a keyword modifier — and getting them in the wrong order silently breaks the effect with no error message.

This guide explains every parameter, shows the most common shadow patterns ready to copy, and links to a visual generator so you can tune shadows by eye.

The syntax

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

A full example:

box-shadow: 4px 8px 16px -2px rgba(0, 0, 0, 0.3);

Breaking it down:

Parameter Value What it does
offset-x 4px Horizontal shift. Positive = right, negative = left.
offset-y 8px Vertical shift. Positive = down, negative = up.
blur-radius 16px Blur amount. 0 = sharp edge, larger = softer.
spread-radius -2px Grows or shrinks the shadow. Negative shrinks it.
color rgba(0,0,0,0.3) Shadow colour, usually semi-transparent black.

Only offset-x and offset-y are required. The rest default to 0 and the current text colour.

The inset keyword

Add inset at the beginning to make the shadow appear inside the element instead of outside:

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

This is useful for pressed-button states, input fields, and sunken panels.

Common shadow recipes

Subtle card shadow

Clean, flat-style card that lifts slightly off the background:

box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);

Two layers: one for the main shadow, one for a sharper contact shadow underneath.

Medium elevation (Material Design style)

box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);

Soft glow effect

box-shadow: 0 0 20px rgba(99, 102, 241, 0.5);

Setting both offsets to 0 and using a coloured shadow creates a glow. Good for focused inputs, highlighted elements, or neon-style UI.

Hard shadow (no blur)

box-shadow: 4px 4px 0 #000;

Zero blur, zero spread. Used in retro/brutalist design or to give buttons a stacked card look.

Inner pressed state

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

Makes an element look pushed in. Use on :active state of buttons.

Bottom shadow only

box-shadow: 0 4px 8px -4px rgba(0, 0, 0, 0.4);

Negative spread (-4px) cancels the sides, leaving only a shadow beneath. Cleaner look for navigation bars and header components.

Layered depth shadow

box-shadow:
  0 2px 4px rgba(0, 0, 0, 0.07),
  0 4px 8px rgba(0, 0, 0, 0.07),
  0 8px 16px rgba(0, 0, 0, 0.07),
  0 16px 32px rgba(0, 0, 0, 0.07);

Four layers with progressively larger values. Creates a smooth, natural depth. Each layer is low-opacity so they don't overpower each other.

Multiple shadows

box-shadow accepts a comma-separated list. They render from front to back (first in the list is on top):

box-shadow:
  0 0 0 3px #fff,       /* white ring */
  0 0 0 5px #6366f1;    /* purple ring outside */

This technique creates outline rings without using the outline property — useful for custom focus indicators.

Performance tips

box-shadow triggers a repaint when it changes (not a reflow), which is better than animating size or position but worse than filter: drop-shadow() in some GPU-accelerated contexts.

For animations:

/* Better for animated shadows */
.card {
  transition: box-shadow 0.2s ease;
}
.card:hover {
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
}

Animating box-shadow is acceptable for simple hover effects. Avoid it on very large elements or complex layouts where repaints are expensive.

For complex shadows that update frequently (e.g. parallax effects), prefer filter: drop-shadow() which runs on the compositor thread. Note that drop-shadow() follows the shape of the element's content, including transparency — box-shadow always follows the box model.

Spread radius use cases

Spread is the most misunderstood parameter:

/* Border substitute — 0 blur, 2px spread */
box-shadow: 0 0 0 2px #6366f1;

This adds a 2px coloured ring around an element — equivalent to a border but without affecting layout. Great for focus rings.

/* Shrink shadow to avoid it peeking on sides */
box-shadow: 0 6px 12px -4px rgba(0, 0, 0, 0.3);

Negative spread compensates for offset — the shadow appears directly under the element without leaking sideways.

Build shadows visually

Instead of tweaking numbers blind, use Toolmingo's Box Shadow Generator. Adjust each parameter with sliders, see the result live, and copy the final CSS. You can add multiple shadow layers and preview against different background colours.

FAQ

Q: What's the difference between box-shadow and filter: drop-shadow()? box-shadow always follows the rectangular box (including transparent areas). filter: drop-shadow() follows the actual visible content — so on a PNG with a transparent background, it creates a shadow around the shape, not the bounding box. drop-shadow() also takes only three parameters (offset-x, offset-y, blur) and has no spread.

Q: Why isn't my shadow visible? The most common cause: the parent element has overflow: hidden set, which clips the shadow. Move the shadow to the parent or remove overflow: hidden. Another cause: the shadow colour has 0 opacity, or the shadow is covered by a higher z-index sibling.

Q: Can I animate box-shadow? Yes. It's a smooth transition between two states. Animating it causes repaints but is generally fine for hover effects. Use will-change: box-shadow if you notice jank, though it has memory trade-offs.

Q: Does box-shadow affect layout? No. Shadows don't take up space in the document flow. They can overlap adjacent elements without pushing them away. If you need the shadow to push other elements, use filter: drop-shadow() inside a wrapper that has extra padding.

Q: What colour format should I use? rgba() for shadows — the alpha channel controls opacity which is more flexible than a fixed light or dark colour. rgba(0, 0, 0, 0.1) to rgba(0, 0, 0, 0.5) covers most use cases. For coloured glows, use the element's accent colour with 40–60% opacity.

Related tools

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools