CSSApril 2026 · 11 min read

CSS Box Shadow: The Definitive Guide

The CSS box-shadow property adds depth, elevation, and visual polish to elements. From subtle card elevation to dramatic neon glows, box-shadow is one of the most versatile CSS properties. This guide covers every aspect — syntax, layering techniques, performance, and production-ready examples.

🌑
Try the Shadow Generator
Build box shadows visually and copy the CSS — free, no signup
DG
Derek Giordano
Designer & Developer
In this guide
01Box-Shadow Syntax02Offset X & Y03Blur Radius & Spread04Shadow Color05Inset Shadows06Layered (Multiple) Shadows07Neumorphism Effect08Colored Glow Effects09Material Design Elevation10Performance Tips11Box-Shadow vs Text-Shadow
⚡ Key Takeaways
  • Master CSS box-shadow: syntax, layered shadows, inset shadows, neumorphism, colored glows, performance tips, and real-world examples with copy-paste code.
  • Covers box-shadow syntax.
  • Covers offset x & y.
  • Covers blur radius & spread.
  • Covers shadow color.

Box-Shadow Syntax

The box-shadow property accepts up to six values in a specific order. Two of them are optional (blur and spread), one keyword is optional (inset), and the color defaults to the element's text color if omitted.

box-shadow: [inset] offset-x offset-y [blur] [spread] color; /* Example */ box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.15);
0 4px 12px

You can also specify multiple shadows separated by commas. Each shadow is rendered independently, and they stack in order — the first shadow in the list appears on top.

Offset X & Y

The first two values control the horizontal (X) and vertical (Y) offset of the shadow relative to the element. Positive X moves the shadow right, positive Y moves it down. Negative values move it left and up respectively.

💡 Tip
Always include -webkit-backdrop-filter alongside backdrop-filter for Safari support. Without the prefix, the effect is invisible to roughly 25% of mobile users.
/* Shadow directly below */ box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.2); /* Shadow to the upper-left */ box-shadow: -4px -4px 16px rgba(0, 0, 0, 0.2);

Setting both offsets to 0 creates a shadow that spreads evenly around the element in all directions — essentially a glow effect. This is the foundation for ambient shadows and neon-style effects.

Blur Radius & Spread

The blur radius determines how much the shadow is blurred. A value of 0 creates a sharp-edged shadow. Larger values create softer, more diffused shadows. The blur radius cannot be negative.

⚠ Warning
On iOS Safari, backdrop-filter inside a position: fixed element can cause severe scroll performance issues. Test thoroughly on real iOS devices.
blur: 0px (sharp)
blur: 24px (soft)

The spread radius expands or contracts the shadow. A positive spread makes the shadow larger than the element. A negative spread makes it smaller. With zero blur and positive spread, you can create solid-colored outlines that don't affect layout.

/* Solid outline effect using spread */ box-shadow: 0 0 0 3px #FF6B6B;

This technique is commonly used for focus rings and selection indicators because, unlike border, box-shadow doesn't affect layout or change element dimensions.

Shadow Color

Shadow colors can be specified in any CSS color format: hex, RGB, RGBA, HSL, or HSLA. Using semi-transparent colors (with RGBA or HSLA) is strongly recommended — solid-color shadows look unnatural because real-world shadows always blend with the surface beneath them.

/* Subtle, natural shadow */ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); /* Brand-colored glow */ box-shadow: 0 4px 20px rgba(255, 107, 107, 0.35);

A good rule of thumb for natural-looking shadows: use black at 8–20% opacity for light backgrounds, and slightly lighter colors at 30–50% opacity for dark backgrounds. Colored shadows (using a darker shade of the element's own color) look more realistic than pure black.

Inset Shadows

Adding the inset keyword moves the shadow inside the element instead of outside it. Inset shadows create the appearance of depth — as if the element is pressed into the surface. They're commonly used for input fields, pressed button states, and concave surfaces.

/* Pressed/indented input field */ box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.3);
inset shadow

You can combine inset and outer shadows on the same element by listing them together. This is useful for creating elements that appear to have both a raised surface and an indented interior.

Layered (Multiple) Shadows

Production-quality shadows almost always use multiple layers. A single shadow looks flat and artificial, while layered shadows mimic how light scatters in the physical world — with a tight, dark shadow near the element and a diffuse, lighter shadow farther away.

/* Layered shadow for realistic elevation */ 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), 0 16px 32px rgba(0, 0, 0, 0.07);
5 layered shadows

The technique above doubles the blur radius and offset at each layer while keeping opacity low. The result is dramatically more realistic than a single shadow with the same total opacity.

Neumorphism Effect

Neumorphism (or "soft UI") uses a combination of light and dark shadows to create elements that appear to extrude from the background surface. The key is matching the shadow colors to the background — the light shadow simulates a highlight from above, and the dark shadow simulates depth below.

/* Neumorphic card on #e0e5ec background */ background: #e0e5ec; box-shadow: 8px 8px 16px #b8bec7, -8px -8px 16px #ffffff;

Neumorphism works best on light, desaturated backgrounds where the highlight shadow (white/light) and depth shadow (dark gray) both blend naturally. It's harder to execute on very dark or very light backgrounds. Try the Ultimate Design Tools Neumorphism Generator to experiment with different surfaces and shadow intensities.

Colored Glow Effects

Colored shadows with zero offset and high blur create a glow effect around elements. This technique is popular for CTAs, featured cards, and brand elements that need to stand out.

/* Coral glow */ box-shadow: 0 0 30px rgba(255, 107, 107, 0.4); /* Layered glow for intensity */ box-shadow: 0 0 10px rgba(255, 107, 107, 0.3), 0 0 30px rgba(255, 107, 107, 0.2), 0 0 60px rgba(255, 107, 107, 0.1);
Layered coral glow

Material Design Elevation

Google's Material Design system uses box-shadow to convey elevation — the apparent height of an element above the page surface. Higher elevation means larger, more diffused shadows. The system defines 25 elevation levels (0–24), each with specific shadow values.

For most projects, three to five elevation levels are sufficient: a flat state (0), a resting card elevation (1–2), a hover/raised state (4–6), and a modal/dialog level (8–16). Each level should visually communicate the element's importance and interactivity.

/* Elevation 1 (resting card) */ box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); /* Elevation 4 (hover state) */ box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); /* Elevation 16 (modal) */ box-shadow: 0 16px 24px 2px rgba(0,0,0,0.14), 0 6px 30px 5px rgba(0,0,0,0.12);

Performance Tips

Box-shadow is a paint operation — changing it forces the browser to repaint the affected area. For most static elements, this is negligible. But there are a few situations where performance matters.

Avoid animating box-shadow directly with transitions. Each frame triggers a repaint. Instead, create a pseudo-element with the target shadow and animate its opacity. The shadow is painted once, and the opacity animation uses the compositor (GPU-accelerated), which is dramatically faster.

.card { position: relative; } .card::after { content: ''; position: absolute; inset: 0; border-radius: inherit; box-shadow: 0 8px 30px rgba(0,0,0,0.3); opacity: 0; transition: opacity 0.3s ease; } .card:hover::after { opacity: 1; }

Very large blur values on large elements can cause visible lag on low-end devices. If you need a 100px+ blur shadow on a large hero section, test on real mobile hardware. Consider using a gradient or image as a fallback for extremely large shadow effects.

Box-Shadow vs Text-Shadow

Box-shadow applies to the element's box — its rectangular (or border-radius-shaped) boundary. Text-shadow applies to the rendered glyphs of text content. They use similar syntax but serve different purposes.

/* Box shadow — on the element container */ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); /* Text shadow — on the text itself */ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);

Text-shadow doesn't support the spread value or the inset keyword. It also doesn't follow the element's border-radius — it follows the shape of each character. Use text-shadow for legibility over images, letterpress effects, and neon text. Use box-shadow for card elevation, focus indicators, and container styling.

Build shadows visually

Use the Ultimate Design Tools Shadow Generator to create layered box shadows with a live preview. Adjust offset, blur, spread, and color — then copy the CSS.

⚡ Open Shadow Generator
DG
Derek Giordano
Written by the creator of Ultimate Design Tools. BA in Business Marketing.
📚 References & Further Reading