---
title: "CSS Box Shadow Generator"
description: "Free CSS box-shadow generator with live preview. Adjust offset, blur, spread, and inset, then copy production-ready CSS for cards, buttons, and modals."
url: https://frontendhelpers.com/box-shadow-generator
updated: 2026-10-12
---

# CSS box shadow generator

Design box shadows with live sliders for offset, blur, spread and opacity — including inset shadows — then copy the CSS.

## How to use this tool

The `box-shadow` property takes its values in a fixed order, and knowing what each one does turns guesswork into intent:

**Horizontal offset** moves the shadow right (positive) or left (negative). **Vertical offset** moves it down or up. **Blur radius** controls how soft the edge is — 0 gives a hard-edged shape, higher values diffuse it. **Spread** grows or shrinks the shadow before blurring, which is the value most people forget exists. **Colour** finishes it, and is almost always best expressed with alpha transparency.

Add `inset` at the start and the shadow is drawn inside the element instead of outside — the standard way to make a field look recessed or a button look pressed.

## Why realistic shadows use low opacity and large blur

The single biggest giveaway of an amateur shadow is opacity that is too high. Real shadows in the physical world are diffuse and subtle; a shadow at 50% black looks like a sticker, not depth. Professional interfaces overwhelmingly use something in the range of 8–25% opacity with a generous blur.

The second giveaway is a shadow with no vertical offset. Light in almost every interface is implicitly from above, so shadows should sit slightly _below_ their element. A shadow offset only horizontally reads as wrong even to people who cannot articulate why.

## Layering shadows for real depth

The technique that separates polished UI from flat UI is stacking multiple shadows in a single declaration, separated by commas. Physical objects cast both a tight, darker contact shadow right at their base and a wider, softer ambient shadow further out. Simulating both is far more convincing than one shadow trying to do everything:

`box-shadow: 0 1px 2px rgba(0,0,0,0.08), 0 8px 24px rgba(0,0,0,0.12);`

Build an elevation scale from this idea — a small shadow for resting cards, a medium one for hover, a large one for modals — and apply it consistently. Consistent elevation is what makes an interface feel like a coherent system rather than a collection of screens.

## Shadows, performance and dark mode

Box shadows are cheap to paint but not free, and animating them can cause repaints on every frame. If you want a lift-on-hover effect, transition `transform` for the movement and keep the shadow change modest — or pre-render two shadow states and cross-fade a pseudo-element, which stays on the compositor.

Dark interfaces need a different approach entirely. A black shadow on a dark background is nearly invisible, so depth has to come from elsewhere: a subtle light border on the top edge, a slightly lighter surface colour, or a coloured glow that matches your accent. That is why this site uses rim highlights and soft coloured glows rather than heavy drop shadows.

## Generating an elevation scale as shadow tokens

Hand-tuning a shadow for every component is how a design drifts. Generate a small numbered scale once, in your build or token pipeline, and have components refer only to `var(--shadow-2)` and friends. The function below pairs a tight contact shadow with a wider ambient one at each level. Two details do most of the work: the ambient layer has a negative spread equal to the level, which stops a large blur bleeding out past the sides of a card, and the colour is a dark shade of the surface hue (slate here) rather than pure black, which turns muddy on tinted backgrounds.

```javascript
// Each level = a tight contact shadow + a wide, softer ambient one.
// rgb is a dark shade of your surface hue, not pure black.
function elevation(level, rgb = '15 23 42') {
  if (level <= 0) return 'none';
  const a1 = (0.06 + level * 0.02).toFixed(2);
  const a2 = (0.04 + level * 0.03).toFixed(2);
  const contact = `0 ${level}px ${level * 2}px rgb(${rgb} / ${a1})`;
  const ambient = `0 ${level * 4}px ${level * 8}px -${level}px rgb(${rgb} / ${a2})`;
  return `${contact}, ${ambient}`;
}

const tokens = [1, 2, 3, 4]
  .map(n => `  --shadow-${n}: ${elevation(n)};`)
  .join('\n');

console.log(`:root {\n${tokens}\n}`);
// :root {
//   --shadow-1: 0 1px 2px rgb(15 23 42 / 0.08), 0 4px 8px -1px rgb(15 23 42 / 0.07);
//   ...
//   --shadow-4: 0 4px 8px rgb(15 23 42 / 0.14), 0 16px 32px -4px rgb(15 23 42 / 0.16);
// }
```

Two limits are worth knowing. `box-shadow` follows the element's `border-radius` but ignores transparency, so a cut-out PNG or an SVG icon gets a rectangular shadow; [`filter: drop-shadow()`](https://developer.mozilla.org/en-US/docs/Web/CSS/filter-function/drop-shadow) follows the alpha channel instead, though it has no spread value and no `inset`. And transitioning between two shadow values repaints the element on every frame. For a hover lift, put the larger shadow on a `::after` pseudo-element and transition its `opacity`, which the browser can hand to the compositor. [MDN's box-shadow reference](https://developer.mozilla.org/en-US/docs/Web/CSS/box-shadow) covers the full syntax, including the stacking order: the first shadow in the list is drawn on top.

## Frequently asked questions

### What do the box-shadow values mean?

In order: horizontal offset, vertical offset, blur radius, spread radius, then colour. Add the inset keyword at the start to draw the shadow inside the element instead of outside it.

### How do I make a subtle, realistic shadow?

Use low opacity (roughly 8–25%), a generous blur, and a small positive vertical offset so the shadow sits below the element. High-opacity shadows with no offset are the most common cause of shadows looking fake.

### Can I add more than one shadow to an element?

Yes — separate multiple shadows with commas. Layering a tight contact shadow with a wider ambient one produces far more convincing depth than a single shadow, and it is how most design systems build their elevation scales.

### How should shadows work in dark mode?

Black shadows barely register on dark backgrounds. Convey depth instead with a lighter surface colour, a subtle top border highlight, or a soft coloured glow matching your accent colour.

## Related tools

- [CSS Gradient Generator](https://frontendhelpers.com/css-gradient-generator): Build linear and radial gradients visually with live preview.
 
- [Colour Palette Generator](https://frontendhelpers.com/color-palette-generator): Generate tints, shades and accents as ready-made CSS tokens.
 
- [72 CSS animations](https://frontendhelpers.com/css-animations): Copy-paste hover lifts, entrances, loaders and more — all pure CSS.

---

This page is a free interactive tool. Use it in your browser at https://frontendhelpers.com/box-shadow-generator
