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;
PartRequiredWhat It Does
offset-xYesHorizontal shift. Positive = right, negative = left
offset-yYesVertical shift. Positive = down, negative = up
blur-radiusNoHow blurry the shadow is. 0 = sharp, larger = softer
spread-radiusNoHow much the shadow expands. Positive = bigger, negative = smaller
colorNo (default = text color)The shadow color
insetNoPuts 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.

Leave a Comment

Your email address will not be published. Required fields are marked *