Layered Box Shadows for Depth: Creating Realistic Elevation in CSS
Single Shadows vs. Layered Shadows
A single box-shadow creates a uniform dark region behind an element. It works, but it looks artificial because real shadows are not uniform — they transition sharply near the object and soften as they spread outward.
Layered shadows approximate this physical behavior by stacking multiple shadow declarations with increasing blur and offset values.
/* Single shadow — flat and artificial */
.card {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
/* Layered shadows — natural depth */
.card {
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.07),
0 4px 8px rgba(0, 0, 0, 0.07),
0 16px 32px rgba(0, 0, 0, 0.07);
}
Notice three things about the layered version:
- Each layer uses the same low opacity — the darkness accumulates naturally
- Each successive layer has larger offset and blur values
- The result looks softer and more dimensional than a single shadow
The Physics of Shadows
In the real world, a light source casts two shadow components:
- Umbra: The darkest area, close to the object, where light is fully blocked
- Penumbra: The softer outer area where light is partly blocked
Layered shadows simulate this by using a tight, darker shadow for the umbra and progressively softer shadows for the penumbra.
Object
│
├─ Umbra (sharp, close)
│ └─ Shadow #1: 0 1px 2px rgba(0,0,0,0.10)
│
├─ Penumbra (soft, medium)
│ └─ Shadow #2: 0 4px 8px rgba(0,0,0,0.07)
│
└─ Penumbra (very soft, far)
└─ Shadow #3: 0 16px 32px rgba(0,0,0,0.05)
Shadow Recipes by Elevation Level
Design systems like Material Design define elevation levels with specific shadow values. Here is a practical set:
Level 1 — Subtle Lift (buttons, chips)
.elevation-1 {
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.05),
0 1px 3px rgba(0, 0, 0, 0.10);
}
Level 2 — Card (cards, dialogs)
.elevation-2 {
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.05),
0 4px 6px rgba(0, 0, 0, 0.07),
0 10px 15px rgba(0, 0, 0, 0.10);
}
Level 3 — Floating (dropdown menus, popovers)
.elevation-3 {
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.05),
0 4px 6px rgba(0, 0, 0, 0.05),
0 10px 15px rgba(0, 0, 0, 0.07),
0 20px 25px rgba(0, 0, 0, 0.10);
}
Level 4 — Modal (modals, overlays)
.elevation-4 {
box-shadow:
0 2px 4px rgba(0, 0, 0, 0.05),
0 8px 16px rgba(0, 0, 0, 0.05),
0 24px 48px rgba(0, 0, 0, 0.10);
}
Dark Mode Shadows
On dark backgrounds, pure-black shadows look harsh and create visible halo effects. Use a tinted shadow color instead — a dark version of your background color works well:
/* Light mode */
.card-light {
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.07),
0 4px 8px rgba(0, 0, 0, 0.07),
0 16px 32px rgba(0, 0, 0, 0.07);
}
/* Dark mode — use the background color as shadow base */
.card-dark {
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.30),
0 4px 8px rgba(0, 0, 0, 0.20),
0 16px 32px rgba(0, 0, 0, 0.15);
}
Some teams prefer colored shadows that match the element's brand color at low opacity:
.brand-shadow {
box-shadow:
0 4px 6px rgba(59, 130, 246, 0.10),
0 12px 24px rgba(59, 130, 246, 0.15);
}
Performance Considerations
Layered shadows are rendered by the browser's compositor and are GPU-accelerated in all modern browsers. Three shadow layers have negligible performance impact.
However, animating box-shadow triggers repaints on every frame. For smooth elevation transitions, animate transform instead and use a CSS transition between shadow states:
.card {
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07), 0 4px 8px rgba(0, 0, 0, 0.07);
transition: box-shadow 0.3s ease, transform 0.3s ease;
}
.card:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.07), 0 16px 32px rgba(0, 0, 0, 0.10);
transform: translateY(-2px);
}
Key Takeaways
- Layered box shadows create natural depth by simulating umbra and penumbra
- Stack 2–4 shadow layers with increasing offset, blur, and consistent low opacity
- Use the same opacity per layer; darkness accumulates naturally
- Dark mode requires adjusted shadow colors — avoid pure black halos
- Colored shadows add polish when used sparingly
- Animate shadows with CSS transitions for smooth hover effects
Try It Yourself
Design layered box shadows interactively with our CSS Box Shadow Generator. Add multiple shadow layers, adjust offsets and blur, then copy the CSS directly into your project.
Related Guides
- CSS Box Shadow Guide — syntax, parameters, and all shadow types
- Box Shadow Animation Techniques — smooth transitions and elevation effects