How to Build the Perfect CSS Box Shadow
Box shadows are one of the most versatile tools in a frontend developer's arsenal. When used well, they create depth, establish visual hierarchy, and guide user attention. When used poorly, they make interfaces look muddy, dated, or amateur.
This guide covers the fundamentals of the box-shadow property, advanced layering techniques, and practical examples you can use immediately.
Understanding the Box Shadow Syntax
The CSS box-shadow property accepts a comma-separated list of shadows. Each shadow has up to five values:
box-shadow: offset-x offset-y blur-radius spread-radius color inset;
Only offset-x and offset-y are required. The others are optional but powerful.
- offset-x: Horizontal distance. Positive moves right; negative moves left.
- offset-y: Vertical distance. Positive moves down; negative moves up.
- blur-radius: How much the shadow is blurred. Larger values create softer shadows. Zero creates a sharp edge.
- spread-radius: Expands or contracts the shadow. Positive expands; negative contracts.
- color: The shadow color. Supports hex, rgb, hsl, and opacity.
- inset: Draws the shadow inside the element instead of outside.
Building Depth with Layered Shadows
A single shadow often looks flat. The most polished designs use multiple stacked shadows to simulate realistic light behavior.
Consider this subtle elevation pattern:
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.05),
0 4px 8px rgba(0, 0, 0, 0.05),
0 8px 16px rgba(0, 0, 0, 0.05);
The first layer provides a tight, immediate shadow. The second adds mid-range diffusion. The third creates a soft ambient glow. Together they produce a smooth depth gradient that mimics real-world physics.
Color and Opacity Best Practices
Black shadows with reduced opacity are generally safer than solid gray shadows. They adapt better to colored backgrounds.
Use rgba(0, 0, 0, 0.1) rather than #CCCCCC. As the background color shifts, a translucent black shadow remains harmonious.
For dark mode, consider using white shadows with low opacity to create depth without harshness:
.dark .card {
box-shadow: 0 4px 12px rgba(255, 255, 255, 0.08);
}
Inset Shadows for Inner Depth
Inset shadows create the illusion of recessed elements, perfect for input fields, wells, and pressed buttons.
input {
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.12);
}
Combining an inset shadow with a subtle border creates a tactile, skeuomorphic feel without the visual noise of heavy gradients.
Common Box Shadow Patterns
Elevation Levels
Map shadows to elevation levels in your design system:
| Level | Usage | Shadow |
|---|---|---|
| 0 | Flat elements | none |
| 1 | Cards, inputs | 0 1px 3px rgba(0,0,0,0.1) |
| 2 | Raised cards, dropdowns | 0 4px 6px rgba(0,0,0,0.1) |
| 3 | Modals, popovers | 0 10px 15px rgba(0,0,0,0.1) |
| 4 | Floating action buttons | 0 20px 25px rgba(0,0,0,0.15) |
Focus Rings
Accessibility requires visible focus states. Instead of removing the default outline, replace it with a themed shadow:
button:focus-visible {
outline: none;
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.4);
}
Neumorphism
Neumorphism blends elements into their background using dual shadows:
.neumorphic {
background: #e0e5ec;
box-shadow:
9px 9px 16px rgb(163,177,198,0.6),
-9px -9px 16px rgba(255,255,255, 0.5);
}
While visually striking, neumorphism suffers from poor accessibility. Ensure sufficient contrast if you use this style.
Performance Considerations
Box shadows are relatively expensive to render during animations and scrolling. Avoid animating the box-shadow property directly. Instead, animate opacity on a pseudo-element with a shadow, or use transform for movement.
For lists with hundreds of items, consider removing shadows or using a single subtle shadow to reduce paint costs.
Using a Generator
Memorizing the perfect shadow values is unnecessary. Our CSS Box Shadow Generator provides a visual interface where you can adjust offset, blur, spread, and color in real time. Copy the generated CSS and paste it directly into your stylesheet.
Summary
- Use multiple layered shadows for realistic depth.
- Prefer translucent black (or white in dark mode) over solid grays.
- Define elevation levels in your design system.
- Pair inset shadows with borders for tactile inputs.
- Always provide visible focus shadows for accessibility.
- Avoid animating box-shadow directly for performance.
Mastering box shadows is about restraint. A single, well-crafted shadow often looks more professional than five competing ones. Start subtle, test on real content, and refine.