The box-shadow property is one of the core tools for creating depth, dimension, and visual hierarchy in interfaces. Unlike outdated approaches that use images or multiple elements, CSS shadows are rendered natively and scale without losing quality. This article covers the syntax, common patterns, and less obvious techniques.
For quick visual shadow adjustments, use the box-shadow generator on reChecker—an interactive tool with a real-time preview.
box-shadow syntax
The full form of the property:
box-shadow: offset-x offset-y blur-radius spread-radius color inset;| Parameter | Description | Default |
|---|---|---|
| offset-x | Horizontal offset (positive values move right) | 0 |
| offset-y | Vertical offset (positive values move down) | 0 |
| blur-radius | Blur radius (0 creates a sharp edge) | 0 |
| spread-radius | Shadow spread (expansion/contraction) | 0 |
| color | Shadow color | browser-dependent (usually black) |
| inset | Keyword that places the shadow inside the element | absent |
All parameters except color can be negative. blur-radius and spread-radius cannot have negative values.
Basic examples
Simple shadow
.card {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}A classic “card” shadow: a 4px downward offset, 6px blur, and semi-transparent black.
Shadow with spread
.button {
box-shadow: 0 0 0 2px #3b82f6;
}With blur-radius: 0 and spread-radius: 2px, this creates the appearance of an outline. Useful for focus states.
Inset shadow
.input {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.06);
}The shadow is drawn inside the element, creating a “pressed-in” effect that works well for input fields.
Multiple shadows
The property accepts multiple shadows separated by commas. Order matters: the first shadow is rendered above the others.
.elevated {
box-shadow:
0 1px 3px rgba(0, 0, 0, 0.12),
0 4px 12px rgba(0, 0, 0, 0.08),
0 0 0 1px rgba(0, 0, 0, 0.05);
}The combination includes a soft, close shadow, a more blurred distant shadow, and a thin outline to sharpen the edges.
Colored shadows
Shadows do not have to be gray. Colored shadows reinforce branding and create expressive hover effects:
.primary-button {
box-shadow: 0 4px 14px rgba(59, 130, 246, 0.4);
}
.primary-button:hover {
box-shadow: 0 6px 20px rgba(59, 130, 246, 0.5);
}Tricks and patterns
Neumorphism
Combining a light outer shadow with a dark inner shadow creates a “raised” effect:
.neo {
background: #e0e5ec;
box-shadow:
6px 6px 12px #bebebe,
-6px -6px 12px #ffffff;
}This works only on a background whose tone is close to that of the element. Consider accessibility: contrast may be insufficient.
Glassmorphism
Shadow + semi-transparent background + backdrop-filter:
.glass {
background: rgba(255, 255, 255, 0.2);
backdrop-filter: blur(10px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
}Animated shadows
Shadows can be animated using transition:
.card {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: box-shadow 0.2s ease;
}
.card:hover {
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}Animating box-shadow affects performance (it triggers a repaint). For complex scenes, filter: drop-shadow() on pseudo-elements or transform is preferable.
Preventing shadows from being clipped while scrolling
To prevent the shadow from being “clipped” by a parent with overflow: hidden, add padding or use margin on the child element.
box-shadow vs. filter: drop-shadow
| Property | Use | Features |
|---|---|---|
| box-shadow | Rectangular element shape | Does not follow the shape of transparent areas |
| filter: drop-shadow | Any shape (including SVG and text) | Follows the alpha channel; one shadow |
/* box-shadow — тень прямоугольника */
.box { box-shadow: 0 4px 8px black; }
/* drop-shadow — тень по контуру */
.icon { filter: drop-shadow(0 4px 8px black); }Performance
Frequent changes to box-shadow (for example, while scrolling) can cause lag. Recommendations:
- Use
will-change: box-shadowonly when necessary, and remove it after the animation - Prefer static shadows over animated ones where possible
- For complex effects, consider pseudo-elements with
transform: translateZ(0)to move them onto a separate layer
Practical recommendations
- Consistency — define 2–3 shadow levels (sm, md, lg) and use them throughout the interface
- Accessibility — shadows do not replace contrast; do not rely on them to convey important information
- Dark mode — reduce shadow intensity or use light-colored shadows on a dark background
- Mobile devices — strong shadows can look excessive on small screens
Experiment with the settings in the reChecker box-shadow generator—visual feedback speeds up the process of finding optimal values.
Ready-made shadow sets
For a quick start, you can use presets that correspond to Material Design or Tailwind:
/* Tailwind-подобные тени */
.shadow-sm { box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); }
.shadow { box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); }
.shadow-md { box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); }
.shadow-lg { box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); }
.shadow-xl { box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); }Adapt the values to your palette and shadow density. The box-shadow generator on reChecker lets you export ready-to-use CSS after visual adjustments.
Browser compatibility
box-shadow is supported in all modern browsers. For IE9 and below, a fallback is required: either omit shadows or use filter: progid:DXImageTransform.Microsoft.Shadow (with limited functionality). In 2026, IE support is not relevant for most projects.
Pseudo-elements and shadows
Shadows on pseudo-elements let you create complex effects without additional markup:
.card::before {
content: '';
position: absolute;
inset: -10px;
background: inherit;
border-radius: inherit;
z-index: -1;
filter: blur(20px);
opacity: 0.5;
}An alternative is box-shadow on a pseudo-element with position: absolute and a negative z-index. The parent must have position: relative and overflow: visible (or sufficient padding).
Shadows for buttons and cards
Recommended values for interactive elements:
| Element | Default state | Hover/Focus |
|---|---|---|
| Button | 0 1px 2px rgba(0,0,0,0.05) | 0 4px 6px rgba(0,0,0,0.1) |
| Card | 0 2px 8px rgba(0,0,0,0.08) | 0 8px 24px rgba(0,0,0,0.12) |
| Modal window | 0 25px 50px rgba(0,0,0,0.25) | — |
Increasing the shadow on hover creates the impression that the element is “rising.” Keep it moderate—excessive contrast is distracting.