The box-shadow Syntax
box-shadow: [inset] offset-x offset-y [blur-radius] [spread-radius] color;
/* Examples */
box-shadow: 2px 4px 8px rgba(0, 0, 0, 0.1);
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
- inset (optional): shadow inside the element instead of outside
- offset-x: horizontal offset — positive = right, negative = left
- offset-y: vertical offset — positive = down, negative = up
- blur-radius (default 0): higher = softer, more spread out shadow
- spread-radius (default 0): expands/contracts shadow before blur; negative = contracts
- color: any CSS color;
rgbafor transparency
Elevation System (Material Design Style)
/* Elevation levels */
--shadow-1: 0 1px 2px rgba(0,0,0,0.05);
--shadow-2: 0 1px 3px rgba(0,0,0,0.1), 0 1px 2px rgba(0,0,0,0.06);
--shadow-3: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -1px rgba(0,0,0,0.06);
--shadow-4: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -2px rgba(0,0,0,0.05);
--shadow-5: 0 20px 25px -5px rgba(0,0,0,0.1), 0 10px 10px -5px rgba(0,0,0,0.04);
/* Usage */
.card { box-shadow: var(--shadow-2); }
.card:hover { box-shadow: var(--shadow-4); transition: box-shadow 0.2s; }
.modal { box-shadow: var(--shadow-5); }
.dropdown { box-shadow: var(--shadow-3); }
Colored Shadows
/* Glow effect — colored shadow, no offset */
.glow-pink {
box-shadow: 0 0 20px rgba(255, 77, 139, 0.5);
}
/* Colored elevation — shadow matches element color */
.button-brand {
background: #6366f1;
box-shadow: 0 4px 14px rgba(99, 102, 241, 0.4);
}
.button-brand:hover {
box-shadow: 0 6px 20px rgba(99, 102, 241, 0.5);
}
Inset Shadow Use Cases
/* Pressed / active state */
.button:active {
box-shadow: inset 0 2px 4px rgba(0,0,0,0.2);
}
/* Inset inner border */
.input:focus {
box-shadow: inset 0 0 0 2px #6366f1;
}
/* Scrollable area top/bottom fade */
.scrollable {
box-shadow:
inset 0 8px 8px -8px rgba(0,0,0,0.1), /* top fade */
inset 0 -8px 8px -8px rgba(0,0,0,0.1); /* bottom fade */
}
Negative Spread for Tight Shadows
/* Soft shadow that doesn't bleed past the element */
box-shadow: 0 4px 8px -2px rgba(0,0,0,0.15);
/* ↑ spread -2px contracts by 2px before blur */
Performance
box-shadow triggers paint (not layout) when changed. Animating it still causes repaints on every frame. For animated shadows, animate opacity on a pseudo-element with a fixed shadow — far cheaper on mobile.
.card::after {
content: '';
position: absolute; inset: 0;
box-shadow: 0 20px 40px rgba(0,0,0,0.2);
border-radius: inherit;
opacity: 0;
transition: opacity 0.2s;
}
.card:hover::after { opacity: 1; }
Generate Box Shadows Visually
Use ToolsVito's Box Shadow Generator to build and preview CSS box shadows interactively — copy the CSS when done.