Build CSS box shadows visually with multiple layers and live preview.
Last updated: September 2026box-shadow: 4px 4px 15px 0px rgba(0, 0, 0, 0.2);
The box-shadow property accepts up to six values. The order matters:
box-shadow: offset-x offset-y blur-radius spread-radius color inset;offset-x — horizontal distance. Positive moves the shadow right, negative moves it left.
offset-y — vertical distance. Positive moves down, negative moves up.
blur-radius — higher values create softer, more diffuse shadows. Zero gives a hard edge.
spread-radius — positive values expand the shadow beyond the element's bounds; negative values contract it. Useful for creating rings or containing a shadow inside the element's silhouette.
color — any CSS color. rgba() lets you control opacity without a separate property.
inset — optional keyword. Moves the shadow inside the element rather than outside it.
Only offset-x and offset-y are required. Omitting blur-radius defaults to 0 (hard shadow); omitting spread-radius defaults to 0 (no expansion).
/* Minimal: hard shadow 4px right, 4px down */
box-shadow: 4px 4px #000;
/* Soft card shadow */
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
/* Negative spread to keep shadow tight */
box-shadow: 0 8px 24px -4px rgba(0, 0, 0, 0.2);
/* Inset (pressed-button effect) */
box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.25);Copy any of these directly into your stylesheet:
1. Subtle card (Material-style elevation 1) — the two-layer approach separates the ambient shadow from the key shadow, producing a more natural look than a single layer:
box-shadow:
0 1px 3px rgba(0, 0, 0, 0.12),
0 1px 2px rgba(0, 0, 0, 0.24);2. Dropdown / popover — more vertical offset signals the panel floats above content:
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15), 0 2px 4px rgba(0, 0, 0, 0.10);3. Button hover state — animate between resting and hover shadows for a lift effect:
.btn { box-shadow: 0 2px 4px rgba(0,0,0,0.18); transition: box-shadow 0.2s ease; }
.btn:hover { box-shadow: 0 6px 16px rgba(0,0,0,0.22); }4. Modal backdrop ring — a spread-heavy shadow works as an overlay indicator without a separate backdrop element:
box-shadow: 0 20px 60px -10px rgba(0, 0, 0, 0.5);5. Neumorphic (soft UI) — dual shadows with one light, one dark, matching the background color:
/* Background must match — here #e0e0e0 */
background: #e0e0e0;
box-shadow: 6px 6px 12px #bebebe, -6px -6px 12px #ffffff;6. Colored glow (focus ring / accent) — use the brand color with high opacity spread for interactive elements:
/* e.g. blue focus ring for accessibility */
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.5);7. Inset (recessed input / pressed state):
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15);8. Multi-layer stacked (high elevation) — three layers simulate physically accurate shadow at different distances:
box-shadow:
0 1px 2px rgba(0,0,0,0.08),
0 4px 8px rgba(0,0,0,0.08),
0 16px 32px rgba(0,0,0,0.12);box-shadow renders against the element's border box — it ignores transparent pixels inside the element. That means a PNG image with a transparent background and a circular subject gets a rectangular shadow, not a circular one.
filter: drop-shadow() follows the element's alpha channel (actual pixel content), so a transparent PNG gets a shadow that hugs its visible shape:
/* box-shadow — rectangular, ignores transparency */
.avatar { box-shadow: 0 4px 12px rgba(0,0,0,0.2); }
/* drop-shadow — follows PNG alpha, correct for images/SVGs */
.avatar { filter: drop-shadow(0 4px 12px rgba(0,0,0,0.2)); }Use box-shadow for rectangular UI components (cards, buttons, modals). Use filter: drop-shadow() for images, SVGs, and irregular shapes where you want the shadow to follow the visible content.
Note: filter creates a new stacking context and affects child elements, which can be surprising. box-shadow does not have this side effect.
box-shadow is a paint property — changing it (or animating it) triggers repaint across the affected area. It does not trigger layout (no geometry change), but it is more expensive than opacity or transform, which are GPU-composited.
opacity on a pseudo-element that has a fixed box-shadow, or use two shadow values and transition between them.will-change: filter when animating drop-shadow — it promotes the element to its own compositor layer. Use sparingly (promotes = uses GPU memory).0 0 0 2px rgba(0,0,0,0.08)) for focus indicators — zero blur means no blur computation, just a solid offset ring.Weekly tips, new tools, and productivity hacks. No spam.