UCSSR
CSS Reference

CSS box-shadow

Complete guide to the CSS box-shadow property — syntax, multiple layers, inset shadows, spread radius, and performance tips.

Overview

The box-shadow property adds one or more shadow effects to an element's frame. Each shadow is described by horizontal and vertical offsets, optional blur and spread radii, color, and an optional inset keyword. Multiple shadows are comma-separated and drawn in order (first listed = topmost). Shadows are essential for creating depth, elevation, focus indicators, and visual hierarchy in modern interfaces.

Syntax

box-shadow: [inset?] <offset-x> <offset-y> [<blur-radius>] [<spread-radius>] [<color>]

Values & Keywords

offset-x
Horizontal offset. Positive = right, negative = left.
offset-y
Vertical offset. Positive = down, negative = up.
blur-radius
Optional. Larger values = softer, more diffuse shadow. Default: 0 (sharp edge).
spread-radius
Optional. Positive = expand shadow, negative = shrink. Default: 0.
color
Shadow color. Use rgba() or hsla() for transparency. Default: currentColor.
inset
Optional keyword. Moves the shadow inside the element border.
none
Removes all shadows. Useful for overriding inherited shadows.

Practical Examples

Subtle card elevation
A gentle shadow with small y-offset and moderate blur creates the illusion of slight elevation — the most common shadow pattern in modern UI.
.card {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12),
              0 1px 2px rgba(0, 0, 0, 0.08);
}
Layered depth (Material Design style)
Stacking multiple shadows with increasing offsets and blur creates a more realistic, layered depth effect. Each layer represents a different light diffusion.
.elevated {
  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),
    0 8px 16px rgba(0, 0, 0, 0.07);
}
Normal
Pressed
Inset shadow for pressed state
The inset keyword creates an inner shadow, making the element appear pressed or recessed — perfect for active button states or input fields.
.button:active {
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
}

.input-field {
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
}
Colorful glow effect
Using the spread radius with a brand color and zero offsets creates a glowing halo effect — great for hover states or highlighting active elements.
.glow {
  box-shadow: 0 0 20px rgba(59, 130, 246, 0.5);
}

.glow-ring {
  box-shadow:
    0 0 0 4px rgba(59, 130, 246, 0.1),
    0 0 0 8px rgba(59, 130, 246, 0.05);
}

Try it visually

Use our interactive box-shadow generator to experiment with values and see the result in real-time. Copy production-ready CSS, cross-browser CSS, or Tailwind classes with one click.

Open CSS box-shadow Tool

Common Patterns

Elevation system
Define shadow tokens at multiple elevation levels for consistent depth across your UI. Reference these as CSS custom properties.
:root {
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
               0 2px 4px -2px rgba(0, 0, 0, 0.1);
  --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1),
               0 4px 6px -4px rgba(0, 0, 0, 0.1);
  --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1),
               0 8px 10px -6px rgba(0, 0, 0, 0.1);
}
Focus ring with box-shadow
A popular technique for accessible focus indicators. Unlike outline, box-shadow respects border-radius and can be styled with color and spread.
.button:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px #ffffff,
    0 0 0 4px #3b82f6;
}
Hover elevation transition
Smoothly increase elevation on hover to provide tactile feedback. Pair with a subtle translate for extra lift.
.card {
  box-shadow: var(--shadow-sm);
  transition: box-shadow 0.2s, transform 0.2s;
}

.card:hover {
  box-shadow: var(--shadow-lg);
  transform: translateY(-2px);
}

Tips & Best Practices

  1. 1

    Use multiple subtle shadows instead of one heavy shadow — stacking 3-4 low-opacity layers creates a much more realistic depth effect than a single shadow.

  2. 2

    Avoid pure black (#000) for shadow colors. Use semi-transparent dark colors like rgba(0, 0, 0, 0.1) — this blends naturally with any background.

  3. 3

    box-shadow does not affect layout — the element size, position, and surrounding elements are unchanged. Use margin or padding to create space if needed.

  4. 4

    For performance-critical animations, prefer box-shadow with will-change: box-shadow or use filter: drop-shadow() which is GPU-accelerated on some browsers.

  5. 5

    Use box-shadow: 0 0 0 3px #3b82f6 as a focus ring — it follows border-radius, unlike outline which is always rectangular in older browsers.

Browser Support

Supported in all modern browsers without prefix. Works in IE9+ (without spread-radius in IE9).

Related CSS Guides

CSS box-shadow — FAQ

Common questions about box-shadow and how to use it effectively.

How do I create a subtle shadow?

Use a small y-offset (2-4px), moderate blur (8-16px), no spread, and a semi-transparent black: box-shadow: 0 2px 8px rgba(0,0,0,0.1). Stack two or three layers with increasing blur for more realism.

Does box-shadow affect layout?

No. box-shadow is purely visual — it does not affect the element's size, position, or the layout of surrounding elements. Shadows can overflow the element's bounding box and overlap adjacent elements.

Can I add multiple shadows?

Yes. Separate each shadow with a comma: box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24). The first shadow is rendered on top.

What is the difference between box-shadow and filter: drop-shadow()?

box-shadow is applied to the element's rectangular box. drop-shadow() follows the element's alpha channel — it can shadow non-rectangular shapes, SVGs, and transparent PNGs. However, drop-shadow() doesn't support inset or spread.

How do I animate box-shadow smoothly?

Animating box-shadow directly can cause repaints. For smoother performance, use a pseudo-element with the target shadow and transition its opacity instead. Or use will-change: box-shadow to hint the browser to optimize.