How to Create Smooth Box Shadows in CSS

Feb 22, 2026·6 min read

If you've ever added a box-shadow to an element and felt like it looked a bit... off, you're not alone. The default approach of using a single shadow layer produces a harsh, unrealistic result. The fix is simple: layer multiple shadows with increasing blur and decreasing opacity. This is the technique used by Material Design, Apple's Human Interface Guidelines, and virtually every polished design system.

The Problem with Single-Layer Shadows

A single box shadow creates a uniform blob of colour behind your element. In the real world, shadows don't work this way — objects cast a sharp, dark shadow close to the surface and a soft, diffused shadow further away. When you use just one box-shadow, you get a result that your brain reads as artificial even if you can't articulate why.

Single layer — flat
Four layers — smooth

The difference is subtle but significant. The left card uses one shadow with a moderate blur. The right card layers four shadows from tight to wide. Your eye reads the right one as physically elevated above the page.

The Layered Shadow Technique

The principle is straightforward: start with a small, tight shadow close to the element, then add progressively larger, softer shadows with lower opacity. Each layer serves a purpose — the tight shadow grounds the element, while the wide shadows create ambient depth.

/* A well-layered shadow */ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 4px 8px rgba(0, 0, 0, 0.06), 0 12px 24px rgba(0, 0, 0, 0.08), 0 24px 48px rgba(0, 0, 0, 0.06);

Notice the pattern: each layer roughly doubles the blur radius of the previous one, while the Y offset increases to push the shadow downward. The opacity stays low across all layers — typically between 0.03 and 0.12 — because the cumulative effect of four or five layers adds up quickly.

Shadow Elevation Levels

Most design systems define 3–5 shadow elevation levels that correspond to different UI states. Here's a practical set you can use directly:

Level 1 — Subtle (cards, containers)

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

Level 2 — Medium (hover states, dropdowns)

box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04), 0 8px 16px rgba(0, 0, 0, 0.08), 0 16px 32px rgba(0, 0, 0, 0.06);

Level 3 — High (modals, popovers)

box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04), 0 8px 24px rgba(0, 0, 0, 0.08), 0 24px 48px rgba(0, 0, 0, 0.1), 0 48px 80px rgba(0, 0, 0, 0.06);

Build it visually → Use our box shadow generator to create layered shadows with a live preview. Includes presets for all elevation levels.

Open Box Shadow Generator

Coloured Shadows

Black or grey shadows are the safe default, but coloured shadows can add polish and personality. The trick is to use a darkened, desaturated version of the element's background colour as the shadow colour. This creates a subtle glow effect that feels more integrated with the design.

/* Coloured shadow using the element's own hue */ background: #7c6aff; box-shadow: 0 2px 4px rgba(124, 106, 255, 0.15), 0 8px 24px rgba(124, 106, 255, 0.25), 0 20px 48px rgba(124, 106, 255, 0.15);

This technique works especially well for buttons and call-to-action elements. The shadow reinforces the button's colour instead of creating a disconnected grey blob beneath it.

Performance Tips

Don't animate box-shadow directly. Changing the shadow value forces the browser to repaint, which is expensive. Instead, use a pseudo-element with the target shadow applied, and transition its opacity. The shadow renders once and the opacity change is GPU-accelerated.

/* Bad — animates paint */ transition: box-shadow 0.2s ease; /* Good — animates composite */ .card::after { content: ''; position: absolute; inset: 0; border-radius: inherit; box-shadow: /* your hover shadow */; opacity: 0; transition: opacity 0.2s ease; } .card:hover::after { opacity: 1; }

This pattern gives you silky smooth hover transitions without jank, even on mobile devices.

Try it yourself → Create layered shadows visually with presets for every elevation level.

Open Box Shadow Generator