CSS Box Shadow: The Complete Guide (with Copy-Paste Examples)

1 6 111
calendar_todayschedule5 min read

The box-shadow property sounds simple — but once you start layering shadows, building card elevation systems, or trying to recreate that exact Figma drop shadow in CSS, the syntax gets complicated fast.

This guide covers everything from the basics to advanced multi-layer techniques, with copy-paste examples throughout.

The Basic Syntax

``css

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

`

Each part explained:

| Parameter | What it does |

|---|---|

| offset-x | Horizontal position. Positive = right, negative = left |

| offset-y | Vertical position. Positive = down, negative = up |

| blur-radius | Edge softness. 0 = crisp, higher = more diffuse |

| spread-radius | Expands (+) or contracts (−) the shadow before blur |

| color | Any valid CSS color, usually rgba() for opacity control |

A simple card shadow:

<code>css <p>.card {</p> <p>box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);</p> <p>}</p> </code>

Inset Shadows

Add the inset keyword to flip the shadow inside the element — useful for pressed button states and recessed input fields:

`css
/ Pressed button /


.btn:active {


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


}

/ Recessed input field /

input {

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

}

`

Multiple Shadow Layers

You can stack multiple shadows with a comma-separated list. The first shadow is drawn on top (closest to the element):

<code>css <p>.card {</p> <p>box-shadow:</p> <p>0 1px 3px rgba(0, 0, 0, 0.12), /<em> tight inner shadow for crispness </em>/</p> <p>0 6px 24px rgba(0, 0, 0, 0.08); /<em> wide outer shadow for ambient depth </em>/</p> <p>}</p> </code>

This two-layer pattern mimics how real shadows work — a bright direct light source creates a sharp inner shadow, while ambient light creates a soft outer glow.

The Four Elevation Levels

Here's a practical elevation scale for UI design:

`css
/ Flat — default state /


.elevation-0 {


box-shadow: none;


}

/ Subtle — cards, sections /

.elevation-1 {

box-shadow: 0 1px 3px rgba(0, 0, 0, 0.10), 0 2px 8px rgba(0, 0, 0, 0.06);

}

/ Standard — hover state, dropdowns /

.elevation-2 {

box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12), 0 8px 24px rgba(0, 0, 0, 0.08);

}

/ Elevated — modals, dialogs /

.elevation-3 {

box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14), 0 16px 48px rgba(0, 0, 0, 0.10);

}

`

Glow Effects

Set both offsets to 0 and use a saturated colour for a glow:

`css
/ Green glow /


.btn-primary:focus {


box-shadow: 0 0 0 3px rgba(47, 133, 90, 0.4);


}

/ Stacked glow for stronger effect /

.notification-badge {

box-shadow:

0 0 8px rgba(229, 62, 62, 0.5),

0 0 24px rgba(229, 62, 62, 0.25);

}

`

Using box-shadow as a Border

box-shadow can replace a border without affecting layout — useful for focus rings and outlines:

`css
/ Focus ring that respects border-radius /


button:focus-visible {


outline: none;


box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.6);


}

/ 2px green border without layout shift /

.selected-card {

box-shadow: 0 0 0 2px #2f855a;

}

`

Neumorphism

The neumorphic trend uses two shadows in opposite directions on a matching background:

`css
/ Element background must match --surface /


:root {


--surface: #e0e5ec;


}

.neumorphic {

background: var(--surface);

box-shadow:

9px 9px 16px #b8bec7, / dark shadow — bottom-right /

-9px -9px 16px #ffffff; / light shadow — top-left /

}

/ Pressed state /

.neumorphic:active {

box-shadow:

inset 4px 4px 8px #b8bec7,

inset -4px -4px 8px #ffffff;

}

`

Animating box-shadow

Animating box-shadow directly triggers a repaint on every frame. For smooth hover transitions, it's still acceptable for most UI:

`css
.card {


box-shadow: 0 2px 8px rgba(0, 0, 0, 0.10);


transition: box-shadow 0.2s ease, transform 0.2s ease;


}

.card:hover {

box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);

transform: translateY(-2px);

}

`

For high-frequency animations (scroll-tied effects), animate opacity on a ::after pseudo-element instead — this stays on the compositor layer.

box-shadow vs filter: drop-shadow()

| | box-shadow | filter: drop-shadow() |

|---|---|---|

| Follows | Element's box | Actual rendered shape |

| Supports inset | ✅ | ❌ |

| Supports spread | ✅ | ❌ |

| Multiple layers | ✅ (comma list) | ❌ (wrap in multiple elements) |

| Best for | Buttons, cards, divs | Transparent PNGs, SVGs |

Converting Figma Shadows to CSS

Figma's shadow panel maps directly to CSS:

  • X → offset-x
  • Y → offset-y
  • Blur → blur-radius
  • Spread → spread-radius
  • Colour + opacity → rgba() or hsla()
  • Inner Shadow → add inset keyword

Quick Reference: Common Patterns

`css
/ Soft card /


box-shadow: 0 1px 3px rgba(0,0,0,0.10), 0 2px 8px rgba(0,0,0,0.06);

/ Material elevation 2 /

box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 2px 4px rgba(0,0,0,0.08);

/ Modal / dialog /

box-shadow: 0 8px 32px rgba(0,0,0,0.15), 0 20px 64px rgba(0,0,0,0.10);

/ Focus ring /

box-shadow: 0 0 0 3px rgba(66,153,225,0.5);

/ Inset (pressed button) /

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

/ Neumorphic (on #e0e5ec background) /

box-shadow: 9px 9px 16px #b8bec7, -9px -9px 16px #ffffff;

/ Remove shadow /

box-shadow: none;

`

Building Shadows Without Guessing

If you'd rather adjust sliders than type raw CSS, the CSS Box Shadow Generator at SnappyTools gives you a live preview with multi-layer support, Figma-style controls, and a one-click copy button. No install, runs 100% in the browser.


The key insight with box-shadow` is that single-layer shadows look flat. Stack a tight, slightly opaque shadow with a wider, more transparent one — and you get depth that actually looks right.

🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

Sovereign Intelligence: The Complete 25,000 Word Blueprint (Download)

Pocket Portfolio - Apr 1

How I Built a React Portfolio in 7 Days That Landed ₹1.2L in Freelance Work

Dharanidharan - Feb 9

TypeScript Complexity Has Finally Reached the Point of Total Absurdity

Karol Modelskiverified - Apr 23

5 Web Dev Pitfalls That Are Silently Killing Your Projects (With Real Fixes)

Dharanidharan - Mar 3

CSS Gradients Explained: Linear, Radial, and Conic with Real Examples

SnappyTools - May 21
chevron_left
2.4k Points118 Badges
101Posts
0Comments
SnappyTools builds free, fast, browser-based tools for developers, writers, and designers. No signup... Show more

Related Jobs

View all jobs →

Commenters (This Week)

2 comments
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!