Subtle. Best for cards, input fields, badges.
1. box-shadow Basics
The box-shadow property takes up to 6 values: offset-x offset-y blur-radius spread-radius color. Only the first two are required.
| Value | What it controls | Required? |
|---|---|---|
| offset-x | Horizontal shift (positive = right, negative = left) | ✅ Yes |
| offset-y | Vertical shift (positive = down, negative = up) | ✅ Yes |
| blur-radius | How soft the shadow is (0 = sharp edge) | No (default 0) |
| spread-radius | Expands (+) or shrinks (−) the shadow before blur | No (default 0) |
| color | Shadow color (use rgba() for opacity control) | No (inherits) |
| inset | Keyword that moves the shadow inside the element | No |
Shadow scale
Standard. Ideal for dropdowns and popovers.
Prominent. Works great for modals and panels.
Hero. Perfect for floating buttons and toasts.
Dramatic. For drawer overlays and fullscreen modals.
/* box-shadow syntax */
/* offset-x | offset-y | blur | spread | color */
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
0 2px 4px -1px rgba(0, 0, 0, 0.06);
/* Shadow scale */
.shadow-sm { box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.08); }
.shadow-md { box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -1px rgba(0,0,0,0.06); }
.shadow-lg { box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -2px rgba(0,0,0,0.05); }
.shadow-xl { box-shadow: 0 20px 25px -5px rgba(0,0,0,0.1), 0 10px 10px -5px rgba(0,0,0,0.04); }
.shadow-2xl { box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25); }2. Understanding Each Value
Isolating each parameter makes it easier to understand what each value does and how to combine them intentionally.
Shadow shifts right. Light source on the left.
Shadow falls below. Light source is above.
Zero blur creates a crisp, hard edge. Great for retro/flat design.
High blur with zero offset creates a diffuse ambient glow.
Positive spread expands the shadow. Use as a focus ring or outline.
Negative spread shrinks the shadow to make the blur look more natural.
/* offset-x only */
box-shadow: 12px 0 8px rgba(0, 0, 0, 0.15);
/* Hard shadow (blur: 0) */
box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.3);
/* Ambient glow (no offset, high blur) */
box-shadow: 0 0 24px rgba(0, 0, 0, 0.3);
/* Focus ring with spread */
box-shadow: 0 0 0 8px rgba(99, 102, 241, 0.25);
/* Natural shadow with negative spread */
box-shadow: 0 8px 16px -8px rgba(0, 0, 0, 0.4);3. Inset Shadows
Add the inset keyword and the shadow appears inside the element. perfect for pressed buttons, recessed inputs, and neumorphic UIs.
Two inset shadows (dark + light) simulate a shallow surface.
Single dark inset shadow creates a sunken/pressed look.
inset 0 0 0 3px creates an inner border without affecting layout.
Combining a dark inset and white inset gives a realistic carved groove.
/* Neumorphic flat surface */
box-shadow: inset 4px 4px 8px #c8cdd2, inset -4px -4px 8px #ffffff;
/* Pressed/sunken button */
box-shadow: inset 0 4px 12px rgba(0, 0, 0, 0.15);
/* Inner border (no layout impact) */
box-shadow: inset 0 0 0 3px #6366f1;
/* Groove / carved effect */
box-shadow: inset 2px 2px 4px rgba(0,0,0,0.12),
inset -2px -2px 4px #ffffff;4. Layered & Multiple Shadows
Comma-separate multiple box-shadow values. Shadows are applied front-to-back. the first value sits on top. Layering creates more naturalistic depth than a single shadow.
Five shadows of increasing size simulate a physically correct shadow.
Combines ambient + directional shadows with a 1px outline for definition.
Spread ring + blur glow create a vibrant colored aura effect.
Each shadow can be a different color for playful multi-color effects.
/* 5-layer natural depth shadow */
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.07),
0 2px 4px rgba(0, 0, 0, 0.07),
0 4px 8px rgba(0, 0, 0, 0.07),
0 8px 16px rgba(0, 0, 0, 0.07),
0 16px 32px rgba(0, 0, 0, 0.07);
/* Colored glow ring */
box-shadow:
0 0 0 3px rgba(99, 102, 241, 0.2),
0 0 20px rgba(99, 102, 241, 0.35),
0 8px 20px rgba(99, 102, 241, 0.2);
/* Multi-color side shadows */
box-shadow:
-6px 0 12px rgba(239, 68, 68, 0.4),
6px 0 12px rgba(99, 102, 241, 0.4),
0 8px 12px rgba(34, 197, 94, 0.3);5. Creative Design Patterns
Shadows serve many design purposes beyond realism. Here are common patterns used in modern UI design, from neumorphism to hard-edge retro styling.
Match the shadow color to the element. Creates a luminous floating effect.
Zero-blur hard shadow with a solid border creates a bold retro/flat-design feel. Animates on hover.
Combine translateY + larger shadow on hover to simulate lifting off the page.
Dark shadow below-right + white shadow above-left on a flat surface color.
Same shadows as raised, but with inset. Element appears pushed in.
Gradient + outer shadows create a tactile domed surface.
/* Colored shadow matching element color */
.btn-indigo {
background: #6366f1;
box-shadow: 0 8px 24px rgba(99, 102, 241, 0.5),
0 2px 6px rgba(99, 102, 241, 0.3);
}
/* Hard retro shadow */
.retro {
box-shadow: 6px 6px 0 #111827;
border: 2px solid #111827;
transition: transform 0.15s, box-shadow 0.15s;
}
.retro:hover {
transform: translate(3px, 3px);
box-shadow: 3px 3px 0 #111827;
}
/* Hover lift */
.card {
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
transition: box-shadow 0.25s ease, transform 0.25s ease;
}
.card:hover {
box-shadow: 0 12px 28px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.06);
transform: translateY(-4px);
}
/* Neumorphism raised */
.neu { background: #e8ecef; }
.neu--raised { box-shadow: 6px 6px 12px #c8cdd2, -6px -6px 12px #ffffff; }
.neu--pressed { box-shadow: inset 4px 4px 8px #c8cdd2, inset -4px -4px 8px #ffffff; }
.neu--convex { background: linear-gradient(145deg, #f0f4f7, #d4d8db);
box-shadow: 6px 6px 12px #c8cdd2, -6px -6px 12px #ffffff; }6. text-shadow
text-shadow works the same as box-shadow but without spread-radius or inset. It follows the letterforms of the text rather than the bounding box.
A simple offset + blur adds readability and dimension.
Four layered pixel-shifted shadows create a retro 3D extrusion.
Three radii of the same color at zero offset creates a neon effect.
Negative Y offsets + warm colors simulate flames rising from text.
Dark shadow below-right + white shadow above-left mimics an embossed stamp.
Four 1px shadows in each diagonal create a crisp text outline.
Hard offset + soft faded copy makes a bold retro-style headline.
/* text-shadow syntax: offset-x | offset-y | blur | color */
/* No spread, no inset */
/* Basic depth */
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25);
/* Long 3D shadow */
text-shadow: 1px 1px 0 #999, 2px 2px 0 #888,
3px 3px 0 #777, 4px 4px 0 #666;
/* Neon glow */
text-shadow: 0 0 8px #818cf8, 0 0 20px #6366f1, 0 0 40px #4f46e5;
/* Fire effect */
text-shadow: 0 -2px 4px #fff, 0 -4px 8px #ff3,
0 -8px 12px #f90, 0 -12px 20px #f80;
/* Emboss */
text-shadow: -1px -1px 0 rgba(255,255,255,0.8),
1px 1px 0 rgba(0,0,0,0.2);
/* Text outline (4 corners) */
text-shadow: -1px -1px 0 #6366f1, 1px -1px 0 #6366f1,
-1px 1px 0 #6366f1, 1px 1px 0 #6366f1;7. drop-shadow() Filter
filter: drop-shadow() is similar to box-shadow, but the shadow follows the actual pixel shape of the element, including transparent areas, clip-path, and SVG contours. Use it on irregular shapes and icons.
Shadow follows the triangle shape, not a rectangle.
A colored drop-shadow creates a chromatic glow around the shape.
Zero blur gives a crisp hard shadow following the icon contour.
A golden drop-shadow at zero offset creates a warm halo.
box-shadow would show a rectangle. drop-shadow follows the star polygon.
box-shadow is a rectangle.
drop-shadow follows the actual shape.
/* drop-shadow syntax (no spread, no inset) */
/* filter: drop-shadow(offset-x offset-y blur color) */
/* Basic shadow */
filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.3));
/* Colored glow */
filter: drop-shadow(0 4px 12px rgba(99, 102, 241, 0.6));
/* Hard edge */
filter: drop-shadow(4px 4px 0 rgba(0, 0, 0, 0.6));
/* Warm halo (zero offset) */
filter: drop-shadow(0 0 8px rgba(251, 191, 36, 0.8));
/* Stack multiple filters */
filter: drop-shadow(0 0 6px #6366f1) drop-shadow(0 0 20px #4f46e5);
/* Differences vs box-shadow:
- No spread-radius value
- No inset keyword
- Follows transparent pixel shape (not bounding box)
- Can't be animated as smoothly in all browsers */