CSS Shadows
Shadows add depth and dimension to flat designs. CSS provides two shadow properties: box-shadow for entire elements and text-shadow for text. Both simulate a light source hitting an object and casting a shadow.
box-shadow
box-shadow draws a shadow around the outside (or inside) of an element's box.
Syntax
box-shadow: [inset] offset-x offset-y [blur-radius] [spread-radius] color;
| Part | Required | What It Does |
|---|---|---|
| offset-x | Yes | Horizontal shift. Positive = right, negative = left |
| offset-y | Yes | Vertical shift. Positive = down, negative = up |
| blur-radius | No | How blurry the shadow is. 0 = sharp, larger = softer |
| spread-radius | No | How much the shadow expands. Positive = bigger, negative = smaller |
| color | No (default = text color) | The shadow color |
| inset | No | Puts shadow inside the element instead of outside |
box-shadow Examples
Simple Drop Shadow
.card {
box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.2);
}
DIAGRAM — Simple shadow:
╔══════════════════╗
║ ║
║ Card content ║
║ ║
╚══════════════════╝
░░░░░░░░░░░░░░░ ← Shadow shifted 4px right, 4px down
Sharp Shadow (no blur)
.retro-box {
box-shadow: 6px 6px 0 black;
}
DIAGRAM — Sharp shadow (blur = 0):
╔══════════════╗
║ Retro Box ║
╚══════════════╝
┌──────────────┐ ← Sharp, no blur, like a sticker effect
Centered Glow Shadow (equal offsets, spread)
.glow-button {
box-shadow: 0 0 15px 5px rgba(52, 152, 219, 0.6);
}
DIAGRAM — Glow effect (x=0, y=0, spread):
░░░░░░░░░░░░░
░░ ░░
░░ [ Glow ] ░░ ← Light radiates equally on all sides
░░ ░░
░░░░░░░░░░░░░
Inset Shadow (inside the element)
input:focus {
box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.2);
}
DIAGRAM — Inset shadow:
╔══════════════════════╗
║░░░░░░░░░░░░░░░░░░░░░ ║ ← Shadow is inside the box
║ ║ (looks like a sunken press)
╚══════════════════════╝
Multiple Shadows
Separate multiple shadows with commas. They layer from front to back.
.layered {
box-shadow:
0 2px 4px rgba(0,0,0,0.1),
0 8px 16px rgba(0,0,0,0.15),
0 24px 48px rgba(0,0,0,0.1);
}
DIAGRAM — Layered shadows (natural depth):
Close shadow: tight, dark
Mid shadow: wider, lighter
Far shadow: widest, lightest
This creates a natural-looking elevation effect.
Negative Spread — Shrinking Shadow
A negative spread radius shrinks the shadow so it only shows on one or two sides, like a directional light source.
.bottom-only {
box-shadow: 0 8px 6px -6px rgba(0, 0, 0, 0.3);
/* The -6px spread cancels the sides, leaving only the bottom */
}
text-shadow
text-shadow works the same way as box-shadow but applies to text characters. It does not have an inset option or spread radius.
Syntax
text-shadow: offset-x offset-y [blur-radius] color;
Subtle Readability Shadow
h1 {
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
Glow Effect on Text
.neon-text {
color: white;
text-shadow:
0 0 5px #fff,
0 0 10px #fff,
0 0 20px #0ff,
0 0 40px #0ff;
}
Multiple Text Shadows — 3D Effect
.three-d-text {
color: #fff;
text-shadow:
1px 1px 0 #ccc,
2px 2px 0 #bbb,
3px 3px 0 #aaa,
4px 4px 0 #999;
}
DIAGRAM — 3D stacked text shadow:
W O R D S
↙↙↙↙↙
Each layer shifts 1px down-right,
creating a layered 3D block effect.
Embossed / Debossed Text
/* Embossed (raised) */
.embossed {
color: #ccc;
background: #ccc;
text-shadow: 1px 1px 2px white, -1px -1px 2px #888;
}
/* Debossed (pressed in) */
.debossed {
color: #ccc;
background: #ccc;
text-shadow: 1px 1px 2px #888, -1px -1px 2px white;
}
CSS filter: drop-shadow() vs box-shadow
For elements with irregular shapes (like a PNG with transparent background), box-shadow draws a shadow around the rectangular bounding box, not the actual shape. Use filter: drop-shadow() instead — it follows the actual shape.
DIAGRAM — box-shadow vs drop-shadow on an irregular PNG:
box-shadow: filter: drop-shadow():
┌─────────────┐ ★
│ ★ │ ░★░ Shadow follows
│ │ ░░░░░ the star shape
└─────────────┘
(Shadow is a rectangle) (Shadow matches the star)
/* For PNG icons and irregular shapes */
.icon {
filter: drop-shadow(2px 2px 4px rgba(0,0,0,0.4));
}
Performance Note
Box shadows and text shadows are rendered by the CPU. Animating them (changing them on hover or with keyframes) can be slow. For smooth animations, animate opacity of a pseudo-element shadow instead of the shadow property itself.
Common Shadow Recipes
/* Subtle card elevation */
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
/* Medium elevation (hover state) */
box-shadow: 0 3px 6px rgba(0,0,0,0.15), 0 2px 4px rgba(0,0,0,0.12);
/* High elevation (modals, dropdowns) */
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
/* Inset well */
box-shadow: inset 0 2px 8px rgba(0,0,0,0.15);
/* Colored brand shadow */
box-shadow: 0 8px 16px rgba(52, 152, 219, 0.4);
Shadows work best when they are subtle and consistent. A single shadow system — one recipe for cards, one for modals, one for hover — makes an interface look intentional rather than scattered.
