Skip to content

Design & Color

Advanced Box Shadow Editor

Stack multiple shadows with live preview.

Runs in your browser

Layer 1

Layer 2

CSS
.card {
  box-shadow: 0px 4px 12px 0px rgba(0, 0, 0, 0.12), 0px 16px 32px -8px rgba(0, 0, 0, 0.20);
}

Understanding stacked box-shadows

Real shadows aren't a single layer.

Why one box-shadow always looks flat, the multi-layer trick that fixes it, and the Material elevation system that codified the idea.

One shadow looks fake.

A real object in real light casts a complex shadow: a sharp dark line right underneath it, fading into a softer ambient shadow further out. One CSS box-shadow value can only represent one of these — pick a small offset for a tight shadow and you lose the ambient softness; pick a big offset for the ambient and you lose the contact line. Both look wrong; one looks too flat, the other looks floating.

Stack two or three layers.

The trick: box-shadow accepts a comma-separated list. Stack a short-distance tight shadow with a longer-distance soft shadow. The combined effect approximates a real object lit from above. box-shadow: 0 1px 2px rgba(0,0,0,0.06), 0 4px 12px rgba(0,0,0,0.10); The first line is the contact shadow; the second is the ambient. Together they read as a real lifted surface.

Material Design's elevation table.

Google's Material Design codified shadow stacks into an elevation scale: dp 1 (closest to surface, smallest shadow), dp 2, dp 4, dp 8, dp 16, dp 24 (furthest from surface, largest shadow). Each level is a specific pair of stacked shadows tuned to look consistent across the system. Once you adopt the scale, every component is one of six elevations and the visual hierarchy is predictable. Tailwind's shadow-* utility classes are basically a port of the same idea.

A worked elegant shadow.

A modal card that wants to feel lifted but not loud: box-shadow: 0 0 0 1px rgba(0,0,0,0.04), 0 2px 4px rgba(0,0,0,0.06), 0 8px 24px rgba(0,0,0,0.08); Three layers: a 1-pixel border-like shadow for the edge definition, a tight contact shadow for depth, an ambient shadow for the lift. Each opacity is low (4-8 %) — multiple soft layers feel more refined than one strong one.

Three-layer card shadow

edge + contact + ambient

Three short opacity values stacked produce one premium effect.

0 0 0 1px @4% + 0 2px 4px @6% + 0 8px 24px @8%

= Lifted, photographic

Coloured shadows.

Default shadows are rgba(0,0,0,…) — neutral grey. Coloured shadows tint them with the dominant accent of the page: rgba(99, 102, 241, 0.2) for a violet brand. The card appears to glow rather than sit. Slightly retro (Tailwind's Cyberpunk and dribbble gradient era), can be very effective on cards highlighted as the primary CTA. Don't apply to every surface; the cost of the technique is that it stops being special once it's everywhere.

Inset for inner shadows.

The inset keyword inverts the shadow into the element. Used for pressed-button states, inset progress bars, "well" effects. Stack inset shadows the same way: inset 0 1px 2px rgba(0,0,0,0.05), inset 0 4px 8px rgba(0,0,0,0.03) gives an inner well. Same multi-layer logic; same gentle opacity rule.

Frequently asked questions

Quick answers.

How do I create a realistic shadow?

Layering multiple shadows is key. Start with a tight, dark shadow for the base and stack a second, softer shadow with a larger blur and lower opacity for the ambient glow.

What is the difference between blur and spread?

Blur softens the edges of the shadow using a Gaussian algorithm. Spread increases or decreases the physical size of the shadow source before the blur is applied.

Does this support inset shadows?

Yes. Each layer can be toggled to `inset`, which places the shadow inside the element's frame to create a sunken or pressed effect.

Is the CSS compatible with all browsers?

The generated `box-shadow` property is supported by all modern browsers. For very old versions of Safari or Firefox, you may need to add `-webkit-` or `-moz-` prefixes manually.

People also search for

Related tools

More in this room.

See all in Design & Color