A little help goes a long way. Find a tool/

Design FIELD NOTES · 4 MIN READ

CSS Shadows: Box vs Text, and How to Write Them

The box-shadow and text-shadow properties compared: offsets, blur, spread, inset, stacked layers, and how border-radius changes the shape of every shadow.

CSS has two shadow properties — box-shadow for boxes and text-shadow for glyphs — and they are not interchangeable. Both are built from the same ingredients (offset, blur, color), but one adds a spread and an inset mode, and both can stack multiple comma-separated layers. Write a value in the wrong shape and the browser silently renders nothing.

Two properties, one idea, different targets

box-shadow paints a shadow around (or inside) an element's border box, and it traces the element's actual outline — rounded corners from border-radius produce rounded shadow corners automatically. text-shadow paints behind rendered text, following each glyph's shape and nothing else. That single difference drives everything else: a box is a geometric object whose edges you control, while text is a outline-shaped stencil the font defines.

The anatomy of box-shadow

A box-shadow value is a short list in a fixed order: two required offsets, then an optional blur, an optional spread, an optional color, and the optional keyword inset (which may sit first or last):

box-shadow: 4px 8px 12px 0 rgba(0, 0, 0, 0.25);
/*           x   y   blur spread color                      */

Positive x pushes the shadow right, positive y pushes it down. The blur softens the edge — it cannot be negative, and zero gives a hard edge. The spread grows (positive) or shrinks (negative) the shadow before the blur is applied, and unlike the blur it may go negative — the trick behind tight "contact" shadows that hug an element's base. The color is optional and defaults to currentColor, the element's own text color. Several shadows can be stacked comma-separated, and the first one listed paints on top.

The classic "floating card" is two layers, not one: a broad, soft, faint shadow for lift, plus a tight, slightly darker one for grounding.

box-shadow:
  0 10px 24px rgba(0, 0, 0, 0.18),
  0 2px 6px rgba(0, 0, 0, 0.12);

text-shadow: the same idea, minus two dials

text-shadow takes offsets, blur, and color — there is no spread and no inset, and a blur of zero gives the crisp drop-shadow that retro sticker typography is built on:

text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.35);   /* classic soft */
text-shadow: 4px 4px 0 #000;                    /* hard retro   */

Where text-shadow gets interesting is stacking, because every layer paints independently of the glyph edges. The neon-glow look is three zero-offset layers with growing blur radii and fading alpha:

text-shadow:
  0 0 4px rgba(179, 255, 54, 0.9),
  0 0 12px rgba(179, 255, 54, 0.55),
  0 0 28px rgba(179, 255, 54, 0.35);

The same stacking can fake effects box-shadow gets for free: a pseudo-spread is several zero-offset layers with increasing blur. One honest caveat — heavy text-shadow blur renders less crisply than box-shadow blur and can hurt legibility, so dense body text rarely benefits from more than a subtle one.

What makes a shadow read as depth

Real-world shadows obey a pattern worth copying. An object far from its surface casts a large, soft, faint shadow: big offset, big blur, low alpha. An object resting on the surface casts a small, tight, darker one. Darkness signals closeness, softness signals height — which is why a huge blurred black blob at 60% opacity reads as dirt, not depth. A spread of zero is the neutral choice; a negative spread pulls the shadow inward so the blurred edges peek out only at the bottom, and a positive spread with zero offsets makes a flat ring or glow around the box. Elevated UI elements also usually lose their shadow when "pressed" — swapping to a smaller offset is what sells the button state change.

Corners first: border-radius shapes every shadow

Because box-shadow follows the border box, your radius decision happens before the shadow does. The border-radius shorthand reads clockwise from the top-left corner: one value for all four corners, or four values in top-left, top-right, bottom-right, bottom-left order:

border-radius: 16px;                 /* every corner      */
border-radius: 12px 24px 12px 24px;  /* TL TR BR BL       */

Two shapes are worth memorizing. A circle is border-radius: 50% on a square element. A pill is a very large pixel value — 999px — on a rectangle; the browser clamps each radius to half the shorter side. Using 50% on a non-square instead produces an ellipse, a common near-miss. Percentages are relative to the box's own dimensions (and can differ per axis), so the same 25% looks different on a wide banner and a tall card. The generator collapses four equal values back to a single value, which is the same shorthand logic the browser applies.

Try it yourself

The CSS Box Shadow Generator builds the value field by field — offsets, blur, spread, color, inset — with a live preview swatch. The CSS Text Shadow Generator does the same for text, with presets including the classic, hard, subtle, neon, and retro looks above, and it stacks layers for you. The Border Radius Generator sets each corner independently in px, %, em, or rem and emits the shortest correct shorthand, so the shadow has the right outline to follow.

Frequently asked questions

Why is my box-shadow not showing up?
The usual suspects: the shadow color equals the background so it blends in, offsets and blur are all zero, a parent clips it with overflow: hidden, or the element has no visible area. Check the value in a preview first — a valid declaration that renders nothing is almost always one of those.
Does text-shadow support spread or inset?
No. text-shadow takes only offset-x, offset-y, blur, and color — spread and inset are box-shadow features. To fake a spread on text, stack several zero-offset layers with increasing blur radii; for an inset look, layer a copy of the text in the background color over the top.
Does box-shadow follow border-radius?
Yes. The shadow is painted around the element's border box outline, so rounded corners produce rounded shadow corners, and the same holds for inset shadows. That is why radius decisions come first: the shadow can only trace the shape you give it.
Can blur or spread be negative in CSS shadows?
Blur cannot be negative — a negative blur radius makes the whole declaration invalid, so nothing renders. Spread can be negative in box-shadow, shrinking the shadow inward; that is how tight "contact" shadows are made. text-shadow has no spread at all.
Do multiple shadows stack, and in what order?
Yes — comma-separate any number of layers for either property. The first shadow in the list paints on top, so put the sharper, darker layer first and the broad soft one behind it. Layer count is also the main cost: many large-blur layers are expensive to repaint.