# CSS Box Shadow Generator for Card and Panel UI

2026-06-19

https://toolblip.com/blog/2026-06-19-css-box-shadow-generator-for-card-and-panel-ui

You type `box-shadow: 2px 2px 4px rgba(0,0,0,0.2)`, refresh the browser, and the shadow looks nothing like what you wanted. Too dark, too offset, bleeding off one edge. Tweak, refresh, squint, repeat.

CSS box-shadow is hard to get right in one shot because you are adjusting five independent parameters. A visual generator that updates the result as you move sliders cuts that loop out entirely.

## What CSS Box-Shadow Actually Controls

The `box-shadow` property takes five values, and you need all of them to get predictable results.

```css
box-shadow: offset-x offset-y blur-radius spread-radius color;
```

**Offset-x** moves the shadow right (positive) or left (negative). A card shadow typically uses 0 or a small positive value like 2px.

**Offset-y** moves the shadow down (positive) or up (negative). Cards use a positive value because light in most UIs comes from above, casting the shadow downward.

**Blur-radius** controls how soft the shadow edge is. Zero blur gives a hard outline like a border. 10px blurs the shadow into a soft glow. This is usually the parameter you increase first when a shadow looks too harsh.

**Spread-radius** expands (positive) or contracts (negative) the shadow size before blurring. A negative spread-radius produces a tighter, more focused shadow that works well for small UI elements like buttons. A positive spread is useful for glow effects.

**Color** should almost always use rgba() or hsla() with an alpha channel. Solid black with opacity looks more natural than a fully opaque color because real shadows are translucent.

```css
/* Hard outline - rarely what you want */
box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.2);

/* Soft, natural card shadow */
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
```

The second example skips spread-radius (defaults to 0) and uses only 2px offset-y with 8px blur. That single combination handles most card UIs.

## Real Box-Shadow Values for Common UI Patterns

Different UI elements need different shadow treatments. These values work across modern browsers and scale well across screen sizes.

### Card shadows

```css
.card-subtle {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}
.card-default {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}
.card-elevated {
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}
```

Three tiers is usually enough. Subtle for stacked layouts where every shadow adds up, default for most cards, elevated for featured content or hover states.

### Modal and overlay shadows

Modals need a stronger, more spread shadow because they sit above everything else on the page. A single strong shadow can look fake. Layering two shadows gives a more realistic effect.

```css
.modal-shadow {
  box-shadow:
    0 2px 8px rgba(0, 0, 0, 0.12),
    0 16px 48px rgba(0, 0, 0, 0.25);
}
```

The first shadow is the tight edge shadow. The second is the broad drop shadow that makes the modal feel like it is floating above the page, not just outlined.

### Button shadows

Buttons need tighter shadows than cards. A button with an 8px blur looks like it is glowing rather than pressed.

```css
.button-raised {
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.button-pressed {
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
}
```

The difference between raised and pressed is 1px offset and halving the blur. That is enough to communicate interactivity without extra motion or color changes.

### Input focus shadows

Focus rings are often done with outline or ring utilities, but box-shadow works too and gives you more control over color and spread.

```css
input:focus {
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.3);
}
```

Using box-shadow for focus indicators avoids the gap between the element edge and an outline that some browsers add. The 0 offsets and 0 blur keep it a sharp ring, and the 3px spread makes it visible without being thick.

## Layering Multiple Shadows

You can stack multiple shadows in a single declaration by comma-separating them. They render from front to back.

```css
.card-layered {
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.04),
    0 2px 4px rgba(0, 0, 0, 0.06),
    0 4px 16px rgba(0, 0, 0, 0.1);
}
```

The first line adds a thin border-replacement outline (1px spread, no blur, low opacity). The second adds a near shadow. The third adds a broad ambient shadow. The card ends up with a defined edge and visible depth, without an actual border.

Material Design uses this technique for its elevation system. Each elevation level is a stack of three shadows that get progressively broader and more transparent.

## Common Mistakes When Writing Box-Shadow Values

**Using px for color.** This does nothing and can break the declaration. Color comes last or second-to-last depending on whether you specify inset.

**Forgetting the commas in multi-shadow stacks.** Missing a comma between shadow layers silently invalidates the entire stack. The browser applies none of them.

**Setting blur-radius to 0 when you meant no blur.** Zero blur gives a hard outline. If you want no visible shadow, either remove the declaration entirely or set all offsets to 0 with a transparent color. A zero-blur black shadow at 50% opacity is a common gotcha - it looks like a misaligned border.

## Why a Visual Box-Shadow Generator Helps

The manual box-shadow process goes: type a value, save, alt-tab to the browser, refresh, examine, alt-tab back, adjust. Eight to twelve seconds per attempt, and a decent shadow takes five to ten tries.

A visual CSS box-shadow generator removes that loop. You drag sliders and see the effect on a sample element instantly. When it looks right, copy the CSS and paste it into your stylesheet.

Use your browser's developer tools to adjust `box-shadow` while you watch the card update. Once the values look right, copy the declaration into your stylesheet and check it at mobile and desktop widths.
