All articles
Visual Effects

10 CSS Box Shadow Techniques Every Developer Should Know

17 February 2025 7 min read Visual Effects

Go beyond the basic drop shadow. Learn layered shadows, inset glow effects, neumorphism, coloured shadows and the exact values that make UI components pop.

The box-shadow property is deceptively simple. One line of CSS, but the difference between a flat, lifeless UI and one that feels tactile and real often comes down to how well you wield it.

Understanding the syntax

Before tricks, let's be precise about what each value does:

box-shadow: [inset] offset-x offset-y [blur] [spread] color;
  • offset-x / offset-y — where the shadow is cast from. 0 0 is directly underneath.
  • blur-radius — how soft the shadow is. 0 = sharp edge.
  • spread-radius — grows or shrinks the shadow before blurring. Negative values shrink it.
  • inset — flips the shadow to the inside of the element.

You can stack multiple shadows with commas. That's where the real power lives.

Technique 1 — Layered shadows for depth

A single shadow looks like a shadow. Multiple shadows at different opacities and distances look like light.

/* Realistic depth effect */
.card {
  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);
}

Each layer represents light interacting at a different distance. The result is a smooth, physically plausible shadow that no single-layer shadow can match.

Technique 2 — Coloured glow effects

Replace black with your brand colour and a large blur radius to create a glow:

/* Amber glow button */
.btn-glow {
  background: #e8a020;
  box-shadow:
    0 0 0 0 transparent,
    0 0 20px rgba(232,160,32,0.5),
    0 0 40px rgba(232,160,32,0.2);
}
.btn-glow:hover {
  box-shadow:
    0 0 0 0 transparent,
    0 0 30px rgba(232,160,32,0.7),
    0 0 60px rgba(232,160,32,0.3);
}
Technique 3 — Inset shadows for pressed states

Inset shadows simulate depth going inward — perfect for pressed buttons and input fields:

/* Pressed button */
.btn:active {
  box-shadow: inset 0 2px 4px rgba(0,0,0,0.3);
  transform: translateY(1px);
}

/* Sunken input */
input:focus {
  box-shadow:
    inset 0 1px 3px rgba(0,0,0,0.2),
    0 0 0 3px rgba(232,160,32,0.25);
}
Technique 4 — Neumorphism

Neumorphism uses two shadows — one dark, one light — to make elements look extruded from their background:

/* Light mode neumorphic card */
.neumorphic {
  background: #e8e8e8;
  box-shadow:
    8px 8px 16px #c8c8c8,
    -8px -8px 16px #ffffff;
  border-radius: 16px;
}

/* Pressed/active state */
.neumorphic:active {
  box-shadow:
    inset 4px 4px 8px #c8c8c8,
    inset -4px -4px 8px #ffffff;
}

The background colour of the element must match the parent — that's what gives it the extruded look. Note: neumorphism has accessibility concerns; use it decoratively, not for critical UI elements.

Technique 5 — Ring / outline without border

Use spread with zero blur to create a crisp ring around an element — great for focus states:

/* Focus ring */
:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(232,160,32,0.6);
}

/* Double ring */
.avatar {
  box-shadow:
    0 0 0 3px var(--bg-primary),
    0 0 0 5px var(--accent);
}