The box-shadow CSS property adds shadow effects around an element's frame. Shadows create depth, visual hierarchy, and polish in web designs. Unlike traditional drop shadow images, CSS box shadows are resolution-independent, easily customizable, and require no HTTP requests.
Box shadows are rendered outside the element's border box by default (outset shadows), or inside the element (inset shadows). They do not affect layout -- other elements position as if the shadow does not exist.
The box-shadow property has universal browser support. All modern browsers and even IE9+ support it without prefixes. For legacy IE8 support (uncommon in 2026), use a filter fallback, but modern projects can safely use box-shadow without vendor prefixes.
The box-shadow property accepts up to six values per shadow, plus an optional inset keyword:
box-shadow: offset-x offset-y blur-radius spread-radius color inset;
| Parameter | Required | Description |
|---|---|---|
| offset-x | Yes | Horizontal offset (positive = right, negative = left) |
| offset-y | Yes | Vertical offset (positive = down, negative = up) |
| blur-radius | No | Blur distance (0 = sharp edge, higher = more blur) |
| spread-radius | No | Shadow expansion (positive = grow, negative = shrink) |
| color | No | Shadow color (defaults to text color) |
| inset | No | Keyword to create an inner shadow |
/* Minimal shadow: offset-x and offset-y only */
.box {
box-shadow: 5px 5px;
}
/* With blur radius */
.box {
box-shadow: 5px 5px 10px;
}
/* With blur and color */
.box {
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.3);
}
/* Complete with spread */
.box {
box-shadow: 5px 5px 10px 2px rgba(0, 0, 0, 0.3);
}
Offset values control where the shadow appears relative to the element. They are the only required parameters.
/* Shadow to the right */
box-shadow: 10px 0 0 black;
/* Shadow to the left */
box-shadow: -10px 0 0 black;
/* No horizontal offset */
box-shadow: 0 0 10px black;
/* Shadow below element */
box-shadow: 0 10px 0 black;
/* Shadow above element */
box-shadow: 0 -10px 0 black;
/* No vertical offset */
box-shadow: 0 0 10px black;
Combine horizontal and vertical offsets for diagonal shadows that simulate light sources:
/* Light from top-left (shadow bottom-right) */
.card {
box-shadow: 10px 10px 20px rgba(0, 0, 0, 0.1);
}
/* Light from bottom-right (shadow top-left) */
.card {
box-shadow: -10px -10px 20px rgba(0, 0, 0, 0.1);
}
/* Light from top (shadow directly below) */
.card {
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
Set both offsets to zero for a shadow that appears evenly around the element:
/* Glow effect - shadow on all sides */
.glow {
box-shadow: 0 0 20px rgba(50, 108, 229, 0.6);
}
Blur radius and spread radius control the shadow's softness and size.
The third parameter controls how blurred the shadow appears. Higher values create softer, more diffuse shadows:
/* Sharp shadow - no blur */
box-shadow: 5px 5px 0 black;
/* Soft shadow - medium blur */
box-shadow: 5px 5px 15px black;
/* Very diffuse shadow - large blur */
box-shadow: 5px 5px 40px black;
The blur radius defines the blur distance. A blur radius of 10px means the shadow transitions from solid to transparent over a 10-pixel distance.
The fourth parameter expands or contracts the shadow before applying blur:
/* Positive spread - shadow grows */
box-shadow: 5px 5px 10px 5px black;
/* Negative spread - shadow shrinks */
box-shadow: 5px 5px 10px -5px black;
/* No spread (default) */
box-shadow: 5px 5px 10px 0 black;
Negative spread is useful for creating shadows that are smaller than the element, preventing shadows from extending too far:
/* Shadow only at the bottom, contained */
.contained-shadow {
box-shadow: 0 10px 20px -10px rgba(0, 0, 0, 0.3);
}
/* Large, soft shadow with spread */
.elevated {
box-shadow: 0 10px 40px 5px rgba(0, 0, 0, 0.15);
}
/* Tight shadow with negative spread */
.subtle {
box-shadow: 0 5px 15px -5px rgba(0, 0, 0, 0.2);
}
Shadow color is the fifth parameter. If omitted, it defaults to the element's text color. For realistic shadows, use colors with transparency.
/* Black shadow */
box-shadow: 5px 5px 10px black;
/* Named color */
box-shadow: 5px 5px 10px gray;
/* Hex color */
box-shadow: 5px 5px 10px #333333;
Use rgba() or hsla() for shadows with transparency. This is essential for realistic, natural-looking shadows:
/* Subtle transparent shadow */
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
/* Darker transparent shadow */
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
/* Colored shadow */
box-shadow: 0 8px 16px rgba(50, 108, 229, 0.2);
Transparent shadows allow background colors and patterns to show through, creating more natural effects:
/* Bad: solid black shadow blocks background */
.card {
box-shadow: 0 4px 6px black; /* Too harsh */
}
/* Good: transparent shadow blends naturally */
.card {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); /* Natural */
}
/* Brand color glow */
.button-primary {
background: #326CE5;
color: white;
box-shadow: 0 4px 20px rgba(50, 108, 229, 0.4);
}
.button-primary:hover {
box-shadow: 0 6px 30px rgba(50, 108, 229, 0.6);
}
/* Neon effect */
.neon {
color: #0ff;
box-shadow:
0 0 10px rgba(0, 255, 255, 0.8),
0 0 20px rgba(0, 255, 255, 0.6),
0 0 30px rgba(0, 255, 255, 0.4);
}
The inset keyword creates inner shadows, making elements appear recessed or carved into the page.
/* Outset shadow (default) - shadow outside element */
.raised {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
/* Inset shadow - shadow inside element */
.recessed {
box-shadow: inset 0 4px 6px rgba(0, 0, 0, 0.1);
}
/* Pressed button effect */
.button:active {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
transform: translateY(1px);
}
/* Input field depth */
input[type="text"] {
border: 1px solid #ddd;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.05);
padding: 0.75rem;
}
/* Neumorphic design */
.neumorphic {
background: #e0e0e0;
box-shadow:
inset 5px 5px 10px rgba(0, 0, 0, 0.1),
inset -5px -5px 10px rgba(255, 255, 255, 0.7);
border-radius: 12px;
}
Use multiple shadows (comma-separated) to combine inset and outset effects:
/* Border illusion with shadows */
.border-shadow {
box-shadow:
0 4px 6px rgba(0, 0, 0, 0.1), /* Outer shadow */
inset 0 1px 0 rgba(255, 255, 255, 0.5); /* Inner highlight */
}
/* 3D button */
.button-3d {
background: linear-gradient(to bottom, #667eea, #764ba2);
box-shadow:
0 8px 16px rgba(0, 0, 0, 0.2), /* Outer shadow */
inset 0 -2px 4px rgba(0, 0, 0, 0.3), /* Bottom inner shadow */
inset 0 2px 4px rgba(255, 255, 255, 0.2); /* Top inner highlight */
}
Apply multiple shadows to a single element by separating them with commas. Shadows are rendered from first to last, with the first shadow on top.
/* Realistic material design shadow - combines close and distant shadows */
.card {
box-shadow:
0 2px 4px rgba(0, 0, 0, 0.1), /* Close shadow for definition */
0 8px 16px rgba(0, 0, 0, 0.1); /* Distant shadow for depth */
}
Material Design uses specific shadow combinations for different elevation levels:
/* Elevation 1: Low elevation (1dp) */
.elevation-1 {
box-shadow:
0 1px 3px rgba(0, 0, 0, 0.12),
0 1px 2px rgba(0, 0, 0, 0.24);
}
/* Elevation 2: Medium elevation (4dp) */
.elevation-2 {
box-shadow:
0 3px 6px rgba(0, 0, 0, 0.16),
0 3px 6px rgba(0, 0, 0, 0.23);
}
/* Elevation 3: High elevation (8dp) */
.elevation-3 {
box-shadow:
0 10px 20px rgba(0, 0, 0, 0.19),
0 6px 6px rgba(0, 0, 0, 0.23);
}
/* Elevation 4: Very high elevation (16dp) */
.elevation-4 {
box-shadow:
0 14px 28px rgba(0, 0, 0, 0.25),
0 10px 10px rgba(0, 0, 0, 0.22);
}
/* Elevation 5: Maximum elevation (24dp) */
.elevation-5 {
box-shadow:
0 19px 38px rgba(0, 0, 0, 0.30),
0 15px 12px rgba(0, 0, 0, 0.22);
}
/* Chromatic aberration effect */
.glitch {
box-shadow:
2px 2px 0 rgba(255, 0, 0, 0.5),
-2px -2px 0 rgba(0, 255, 255, 0.5);
}
/* Rainbow shadow */
.rainbow-shadow {
box-shadow:
0 0 20px rgba(255, 0, 0, 0.3),
0 0 30px rgba(255, 127, 0, 0.3),
0 0 40px rgba(255, 255, 0, 0.3),
0 0 50px rgba(0, 255, 0, 0.3),
0 0 60px rgba(0, 0, 255, 0.3),
0 0 70px rgba(75, 0, 130, 0.3),
0 0 80px rgba(148, 0, 211, 0.3);
}
Box shadows enable a wide range of creative effects beyond simple drop shadows.
.neumorphic {
background: #e0e0e0;
border-radius: 20px;
padding: 2rem;
box-shadow:
20px 20px 60px rgba(0, 0, 0, 0.15),
-20px -20px 60px rgba(255, 255, 255, 0.7);
}
.neumorphic-button {
background: #e0e0e0;
border: none;
border-radius: 12px;
padding: 1rem 2rem;
box-shadow:
5px 5px 10px rgba(0, 0, 0, 0.1),
-5px -5px 10px rgba(255, 255, 255, 0.7);
}
.neumorphic-button:active {
box-shadow:
inset 5px 5px 10px rgba(0, 0, 0, 0.1),
inset -5px -5px 10px rgba(255, 255, 255, 0.7);
}
.stacked-cards {
position: relative;
background: white;
border-radius: 8px;
padding: 2rem;
box-shadow:
0 3px 6px rgba(0, 0, 0, 0.1),
0 6px 12px rgba(0, 0, 0, 0.08),
0 9px 18px rgba(0, 0, 0, 0.06);
}
/* Alternative: pseudo-elements for more cards */
.stacked-cards-alt {
position: relative;
background: white;
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1);
}
.stacked-cards-alt::before,
.stacked-cards-alt::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
background: white;
border-radius: inherit;
z-index: -1;
}
.stacked-cards-alt::before {
top: 4px;
left: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
}
.stacked-cards-alt::after {
top: 8px;
left: 8px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
}
/* Soft glow */
.glow-soft {
box-shadow: 0 0 20px rgba(50, 108, 229, 0.4);
}
/* Pulsing glow animation */
@keyframes pulse-glow {
0%, 100% {
box-shadow: 0 0 20px rgba(50, 108, 229, 0.4);
}
50% {
box-shadow: 0 0 40px rgba(50, 108, 229, 0.8);
}
}
.glow-pulse {
animation: pulse-glow 2s ease-in-out infinite;
}
/* Neon glow */
.neon-glow {
color: #0ff;
text-shadow: 0 0 10px #0ff;
box-shadow:
0 0 10px rgba(0, 255, 255, 0.8),
0 0 20px rgba(0, 255, 255, 0.6),
0 0 30px rgba(0, 255, 255, 0.4),
0 0 40px rgba(0, 255, 255, 0.2);
}
.card-lift {
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
box-shadow:
0 1px 3px rgba(0, 0, 0, 0.12),
0 1px 2px rgba(0, 0, 0, 0.24);
}
.card-lift:hover {
transform: translateY(-8px);
box-shadow:
0 14px 28px rgba(0, 0, 0, 0.25),
0 10px 10px rgba(0, 0, 0, 0.22);
}
Follow these guidelines to create performant, accessible box shadows.
Box shadows can impact rendering performance, especially when animated or used on many elements:
/* Bad: animating box-shadow directly (triggers paint) */
.button {
transition: box-shadow 0.3s;
}
.button:hover {
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);
}
/* Good: use transform and opacity (GPU-accelerated) */
.button {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
transition: transform 0.3s, opacity 0.3s;
}
.button::after {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);
opacity: 0;
transition: opacity 0.3s;
}
.button:hover::after {
opacity: 1;
}
:root {
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
--shadow-md: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
--shadow-lg: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
--shadow-xl: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
}
.card {
box-shadow: var(--shadow-md);
}
.modal {
box-shadow: var(--shadow-xl);
}
Shadows are visual only and do not convey information to screen readers. Don't rely on shadows alone to indicate important states:
/* Bad: only shadow indicates error */
.input-error {
box-shadow: 0 0 0 3px rgba(255, 0, 0, 0.3);
}
/* Good: combine with border and aria attribute */
.input-error {
border: 2px solid #dc3545;
box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.25);
aria-invalid: true;
}
@media (prefers-reduced-motion: no-preference) {
.card {
transition: box-shadow 0.3s, transform 0.3s;
}
.card:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-lg);
}
}
@media (prefers-reduced-motion: reduce) {
.card {
transition: box-shadow 0.3s;
}
.card:hover {
/* No transform, just shadow change */
box-shadow: var(--shadow-lg);
}
}
While you can use many shadows, limit them for performance:
Our free CSS Box Shadow Generator lets you create custom box shadows visually and export production-ready CSS code.
Adjust shadow properties with intuitive sliders and see changes in real-time. Control offset, blur, spread, color, and opacity with visual feedback.
Add multiple shadow layers to create complex, realistic effects. Each layer has independent controls, and you can reorder layers by dragging.
Start with professionally designed shadow presets:
Preview your shadow on different elements (card, button, input) and background colors to ensure it works in various contexts.
Design professional box shadows with our visual generator. Adjust offset, blur, spread, and color in real-time, then export production-ready CSS code -- all in your browser.
Try the Box Shadow GeneratorMaster linear, radial, and conic gradients with color stops, repeating patterns, and effects.
Learn CSS minification techniques, file size reduction strategies, and performance optimization.
Master color format conversion between HEX, RGB, HSL, and HSV with examples.