Preview
Box Shadow Preview
Generated CSS

CSS Box Shadow: Complete Guide

The CSS box-shadow property adds one or more shadow effects around an element's box. Shadows are essential for creating depth, elevation and visual separation in modern UI design — buttons, cards, modals, dropdowns and tooltips all rely on them. Unlike image-based shadows, CSS box shadows are crisp at any resolution, load instantly, and can be animated.

Use the generator above to build single or multi-layer shadows visually, then copy the CSS directly into your project.

How to Use This Box Shadow Generator

  1. Add as many shadow layers as you need — Click "+ Add Layer" to stack shadows for realistic depth, neumorphism, or glow effects.
  2. Tune each layer — Use the X/Y offset, blur, spread, opacity and color sliders. Toggle Inset for inner shadows.
  3. Copy the CSS — Hit Copy Code to grab the full multi-layer CSS with all your shadows combined into one declaration.

box-shadow Syntax

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

/* Multiple layers (comma-separated) */
box-shadow:
  0 2px 4px rgba(0,0,0,0.1),
  0 8px 24px rgba(0,0,0,0.15);

Understanding Each Value

offset-x — Horizontal shadow position. Positive moves right, negative moves left.

offset-y — Vertical shadow position. Positive moves down, negative moves up.

blur-radius — How soft the shadow edge is. 0 = sharp. Higher = more diffused.

spread-radius — Expands or contracts the shadow size. Positive = larger than the element. Negative = smaller.

color — The shadow color. Use rgba() to control opacity.

Common Shadow Recipes

/* Subtle card lift */
box-shadow: 0 1px 3px rgba(0,0,0,0.1), 0 4px 12px rgba(0,0,0,0.08);

/* Elevated modal */
box-shadow: 0 8px 32px rgba(0,0,0,0.24), 0 2px 8px rgba(0,0,0,0.12);

/* Soft bottom shadow only */
box-shadow: 0 4px 16px -4px rgba(0,0,0,0.2);

/* Coloured glow */
box-shadow: 0 0 0 1px #7c6fff, 0 0 20px rgba(124,111,255,0.4);

/* Pressed button (inset) */
box-shadow: inset 0 2px 4px rgba(0,0,0,0.3), inset 0 1px 2px rgba(0,0,0,0.2);

/* No shadow (reset) */
box-shadow: none;

Inset Shadows

The inset keyword moves the shadow inside the element boundary — useful for pressed button states, inner glow effects, and UI elements that need to appear recessed into the surface.

/* Input field focus ring using inset */
.input:focus {
  box-shadow:
    inset 0 1px 3px rgba(0,0,0,0.15),
    0 0 0 3px rgba(124,111,255,0.25);
}

/* Inner glow */
.glow-card {
  box-shadow: inset 0 0 30px rgba(124,111,255,0.2);
}

Multi-Layer Shadows for Realism

Real-world objects cast complex shadows with multiple components — a sharp close shadow and a soft diffuse shadow further away. Layering two shadows closely mimics this and produces much more realistic depth than a single layer.

/* Layered realistic shadow (low elevation) */
.card {
  box-shadow:
    0 1px 2px rgba(0,0,0,0.07),
    0 2px 4px rgba(0,0,0,0.07),
    0 4px 8px rgba(0,0,0,0.07);
}

/* High elevation — modal/dialog */
.modal {
  box-shadow:
    0 2px 4px rgba(0,0,0,0.08),
    0 8px 16px rgba(0,0,0,0.1),
    0 24px 48px rgba(0,0,0,0.12);
}

Animating box-shadow

box-shadow can be transitioned, but it is expensive because it triggers a repaint on every frame. For animated hover effects, a performance trick is to pre-render the shadow using opacity: 0 on a pseudo-element and fade that in instead of transitioning box-shadow directly.

/* Simple transition (OK for occasional use) */
.card {
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  transition: box-shadow 0.25s ease;
}
.card:hover {
  box-shadow: 0 8px 32px rgba(0,0,0,0.2);
}

Browser Support

box-shadow has been universally supported since 2011 — completely safe to use without prefixes or fallbacks. It respects border-radius, but does NOT follow clip-path shapes (use filter: drop-shadow() for that).

FeatureChromeFirefoxSafariEdge
box-shadow10+4+5.1+12+
inset shadows10+4+5.1+12+
multi-layer10+4+5.1+12+
box-shadow animation26+16+7+12+

Frequently Asked Questions

How do I create a neumorphism shadow in CSS?

Stack two shadows with opposite directions — one dark below-right, one light above-left, both on a background that matches the element. Example: box-shadow: 8px 8px 16px #b8b9be, -8px -8px 16px #ffffff. The element should share the same background color as its parent for the soft, embedded look.

What's the difference between inset and outset box-shadow?

Default (outset) shadows project outward from the element's edge. Adding the inset keyword flips the shadow inward, making the element appear pressed in or recessed. Inset shadows are useful for input field focus rings, pressed button states and recessed UI panels.

How do I make a soft drop shadow?

Use a small Y offset, a large blur radius, and low opacity: box-shadow: 0 8px 24px rgba(0,0,0,0.08). The key is high blur with low opacity. Stack a second tighter shadow for added depth: box-shadow: 0 8px 24px rgba(0,0,0,0.08), 0 2px 6px rgba(0,0,0,0.06).

Can I animate box-shadow?

Yes, but it's expensive — animating box-shadow forces a repaint every frame. For smooth performance, animate the opacity of a pseudo-element with the shadow on it, or use transform: scale() to fake elevation changes. The Animating box-shadow section above has the optimized pattern.

box-shadow vs filter: drop-shadow — which should I use?

Use box-shadow for rectangular UI elements (cards, buttons, panels) — it's faster and respects border-radius. Use filter: drop-shadow() for irregular shapes — it follows transparent areas in PNGs and clip-path edges, which box-shadow can't do. For most UI work, box-shadow is the right choice.

How do I add multiple shadows to one element?

Comma-separate them in a single box-shadow declaration. Each shadow renders top-down — the first shadow listed appears on top. Layering 2-4 shadows produces realistic depth: a tight inner shadow for the edge plus a wider outer shadow for ambient elevation.

Need a shadow that follows the actual shape of an element rather than its bounding box? Use our CSS Filter Generator with drop-shadow() instead.

Tool last updated: