This CSS box shadow generator builds production-ready shadows with visual sliders for offset, blur, spread, color and the inset keyword. Stack unlimited shadow layers to create Material-style elevations, neumorphic surfaces, neon glows, or soft ambient lighting. Every change updates the live preview and rewrites the CSS in real time, so you can copy the finished declaration straight into your stylesheet. Pick a preset to start fast, or dial in custom values on both axes. All calculation runs in your browser — no sign-up, no tracking, works offline once the page is cached.
The box-shadow property is one of the oldest CSS3 features — yet good shadows still distinguish a polished interface from one that looks like a wireframe. This guide unpacks the syntax (each of the four numeric values does something specific), the physics-aware patterns Google's Material team and Apple's Human Interface team use to build elevation systems, the new filter: drop-shadow() alternative for irregular shapes, and the performance pitfalls that cause shadow-heavy pages to drop frames during scroll.
The full box-shadow grammar from CSS Backgrounds and Borders Module Level 3:
box-shadow: [inset?] <offset-x> <offset-y> [blur-radius] [spread-radius] [color];
| Value | Effect | Direction of "+" |
|---|---|---|
| offset-x | Horizontal shift | Positive = shadow to the right |
| offset-y | Vertical shift | Positive = shadow below the element |
| blur-radius | How soft the edge is | 0 = hard edge; large = diffuse |
| spread-radius | Grow / shrink before blur | Positive = bigger; negative = inset-clipped |
| color | Shadow color (any CSS color) | Default = current text color |
| inset | Paint inside the box | Default is outer (drop) shadow |
The blur and spread interact in non-obvious ways. A 24 px blur with 0 spread creates a 24-pixel-wide gradient on each edge. A −12 px spread with a 24 px blur shrinks the source rectangle first, so you only see the right half of the gradient — useful for tight inner-glow effects.
Real-world shadows are not a single blur. A pen on a desk in a sunlit room casts:
Material Design and Apple's HIG both encode this in their elevation systems. A typical 8-dp Material card:
box-shadow:
0 1px 2px rgba(0,0,0,.10), /* contact */
0 4px 8px rgba(0,0,0,.08), /* key */
0 12px 24px rgba(0,0,0,.06); /* ambient */
The pattern is: progressively bigger offset and blur, progressively lower opacity. Designers call the result "smell of money" — UIs that feel premium without anyone being able to articulate why.
The Material 3 elevation tokens, translated to CSS box-shadow:
| Level | Use for | Box-shadow |
|---|---|---|
| 0 | Flat surfaces, app bar at rest | none |
| 1 | Cards, switches, raised buttons | 0 1px 2px rgba(0,0,0,.30), 0 1px 3px 1px rgba(0,0,0,.15) |
| 2 | FAB rest, snackbars | 0 1px 2px rgba(0,0,0,.30), 0 2px 6px 2px rgba(0,0,0,.15) |
| 3 | FAB hover, navigation drawer | 0 1px 3px rgba(0,0,0,.30), 0 4px 8px 3px rgba(0,0,0,.15) |
| 4 | Dialogs, picked-up items | 0 2px 3px rgba(0,0,0,.30), 0 6px 10px 4px rgba(0,0,0,.15) |
| 5 | Modal overlays | 0 4px 4px rgba(0,0,0,.30), 0 8px 12px 6px rgba(0,0,0,.15) |
Soft-UI / neumorphic surfaces look extruded out of the background. The trick: two opposing shadows, one lighter than the surface, one darker.
background: #e0e5ec;
box-shadow:
9px 9px 18px #a3b1c6, /* darker, bottom-right */
-9px -9px 18px #ffffff; /* lighter, top-left */
Neumorphism died as a mainstream trend around 2022, partly because the low-contrast aesthetic is an accessibility nightmare. Use it for marketing pages and design portfolios where contrast is decorative; do not ship it in transactional UI.
The inset keyword paints the shadow inside the box. Use cases:
inset 0 1px 0 rgba(255,255,255,.15) across the top edge mimics a subtle bevel.inset 0 2px 4px rgba(0,0,0,.06) makes the field feel carved into the surface.| Aspect | box-shadow | filter: drop-shadow() |
|---|---|---|
| Shape followed | Box (with border-radius) | Actual painted shape (incl. transparent PNG / SVG cut-outs) |
| Spread radius | Yes | No |
| Inset shadows | Yes | No |
| Multiple shadows | Comma-list | Chain drop-shadow() calls |
| Performance | Lower GPU cost | Higher cost (creates new stacking context) |
| Best for | Cards, buttons, rectangles with rounded corners | Logos, SVG icons, irregular shapes, PNG with transparency |
Box-shadows are GPU-accelerated, but each shadow layer creates a paint area equal to the element rectangle plus the shadow extent on every side. A 0 0 100px 100px shadow on a 200×200 box covers 600×600 pixels — nine times the original area. Multiply by stacked layers and you can blow out paint cost on weaker mobile GPUs.
The defensive habits:
opacity, not the shadow itself. Put the shadow on a pseudo-element and fade it in — much cheaper than recomposing blur.transform: translate3d(0,0,0) or will-change: transform on the parent to promote it to its own compositor layer.rgba(17,24,39,.15) or similar; pure black looks like a stage prop.box-shadow: 0px 4px 12px black is fine; 0 4px 12px black is also valid (CSS lets you drop the unit on zero), but mixing styles in one codebase is messy.:focus-visible and outline; users with custom OS contrast settings rely on outline. Replace it with a shadow only when you also re-add an accessible focus indicator.box-shadow on every frame. Use opacity or transform-based hover effects.inset keyword. Positive h-offset moves the shadow to the right; positive v-offset moves it down. Blur softens the edge — a blur of 0 creates a hard-edged shadow, while larger values create a diffuse gradient. Spread grows or shrinks the whole shadow uniformly before blurring. The inset keyword paints the shadow inside the element instead of outside.box-shadow declaration. The first shadow renders on top of the next, so layer your sharp, close shadows first and softer, wider shadows after. Stacking is how designers achieve Material Design elevations (typically three layers: ambient, key, and contact), neumorphic surfaces (one light and one dark shadow from opposite directions), and realistic ambient lighting. This generator supports as many layers as you need — use the + Add layer button to create a new one.will-change: box-shadow hint, or animate a pseudo-element's opacity instead of the shadow property itself to keep the animation on the compositor thread. Avoid animating the blur radius on every frame.rgba(17, 24, 39, 0.15)) reads as more natural because real-world shadows pick up ambient color tint. The Paper and Soft presets above demonstrate this layered approach.border-radius, so a rounded card gets a rounded shadow without any extra work. This is different from filter: drop-shadow(), which follows the actual painted shape including transparent PNG edges. Use box-shadow for rectangular and rounded-rectangular elements; use drop-shadow for irregular shapes, SVG icons, or elements with transparent cut-outs.All tools run in your browser, no signup required, nothing sent to a server.