CSS Box Shadow Generator
Build CSS box shadows by stacking layers — each with its own offsets, blur, spread, color, alpha, and inset flag — and watch the result live on a light, dark, or custom background so you can actually see a 3%-alpha shadow before you ship it. One click copies clean multi-line CSS or a Tailwind arbitrary-value class. Presets cover the classics: Material elevations, the five-layer "smooth" stack, neumorphism, and a hard retro offset.
0px 1px 3px rgba(0, 0, 0, 0.12)0px 1px 2px rgba(0, 0, 0, 0.24)box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.12), 0px 1px 2px rgba(0, 0, 0, 0.24);
shadow-[0px_1px_3px_rgba(0,0,0,0.12),0px_1px_2px_rgba(0,0,0,0.24)]
How to use the css box shadow generator
- Start from a preset chip, or add layers manually with + Add layer.
- Drag the sliders (or type exact values) for X/Y offset, blur, and spread; pick the color and dial the alpha down — realistic shadows are usually black at 3–20% opacity, not gray at 100%.
- Use the Hide toggle to A/B a layer's contribution, reorder with the arrows, and switch the preview background to match the surface your real UI uses.
- Copy the CSS (one layer per line, comment-friendly) or the Tailwind shadow-[…] string.
Blur vs spread — what each value actually does
The syntax is box-shadow: x y blur spread color. The two offsets move a copy of the element's silhouette; positive Y pushes it down, matching light from above. Blur feathers the silhouette's edge with a Gaussian falloff — at blur: 12px the shadow fades out over roughly 12px on each side of the edge, without making the shadow meaningfully bigger. Spread resizes the silhouette itself before blurring: spread: 4px grows it 4px in every direction, while a negative spread shrinks it. That's the trick behind Material-style elevations like 0 5px 5px -3px: the negative spread pulls the dark core inward so only the soft blurred fringe peeks out below the card. A common beginner mistake is reaching for spread to make a shadow "bigger" — that produces a hard dark slab; you almost always want more blur and lower alpha instead.
Why layered shadows look real
A real shadow isn't one gradient — it's the sum of a tight, dark contact shadow where the object nearly touches the surface and a wide, faint penumbra from ambient light. One box-shadow layer can't express both, which is why single-layer shadows read as flat gray halos. The five-layer "Smooth" preset approximates the physical falloff by doubling each layer's distance and blur (1, 2, 4, 8, 16px) while keeping alpha tiny (3–6%) — the layers overlap most near the element, so darkness concentrates at the contact point and decays naturally outward, the same easing-curve idea Tobias Ahlin popularized for CSS shadows. Material Design encodes the same physics differently: each elevation is three layers — a negative-spread "umbra", a soft "penumbra", and a wide low-alpha "ambient" — which is exactly what the Material 1/4/8 presets reproduce.
Performance and dark mode
Performance: box-shadow costs nothing while static — it rasterizes once with the element. It gets expensive when it repaints: animating box-shadow directly forces a repaint every frame, and a 200px blur over a large card is a lot of pixels to re-blur. The standard trick is to keep two pre-rendered states — the element's resting shadow plus a ::after pseudo-element holding the hover shadow at opacity: 0 — and animate only the pseudo-element's opacity, which the compositor handles off the main thread. Five low-alpha layers on a static card, however, are perfectly fine; don't let the layer count scare you.
Dark mode: shadows barely register on dark surfaces — there's nothing darker to cast onto. Material's answer is to communicate elevation by lightening the surface itself (a white overlay from about 5% at low elevation to 16% at the highest) and keep only a faint shadow for edge definition. Practical recipe: in dark themes, raise the card's background a step, drop shadow alpha roughly in half, and consider a 1px low-alpha white border or inset highlight on the top edge to suggest a lit rim. Use this tool's dark preview background to verify the effect instead of guessing.
Frequently asked questions
What does each number in box-shadow mean?
In order: offset-x, offset-y, blur-radius, spread-radius, then the color — e.g. box-shadow: 0 4px 12px -2px rgba(0,0,0,0.15). Offsets move the shadow (positive y is down), blur softens its edge, spread grows (positive) or shrinks (negative) the shadow before blurring, and an optional 'inset' keyword at the start draws it inside the element instead of behind it. Blur and spread cannot be negative and positive respectively in the same sense: blur has a 0 floor, spread can go negative.
Why does my shadow look like a dirty gray smudge?
Almost always too much alpha and too little blur, or a pure-gray color. Realistic shadows are black (or the background's hue, darkened and desaturated) at low opacity: try 0 4px 12px rgba(0,0,0,0.10) instead of 0 2px 4px rgba(128,128,128,0.8). On colored backgrounds, tinting the shadow toward the background color (e.g. a blue-gray like rgba(50,50,93,0.25) on a blue page) looks dramatically more natural than neutral black.
How do I use the generated shadow in Tailwind CSS?
Copy the shadow-[…] output — it's Tailwind's arbitrary-value syntax, with spaces encoded as underscores and layers separated by commas, e.g. shadow-[0_1px_3px_rgba(0,0,0,0.12),0_1px_2px_rgba(0,0,0,0.24)]. It works in Tailwind v3 and v4 as-is. If you reuse the shadow across the project, promote it to a design token instead: in v4 add --shadow-card: …; under @theme and use shadow-card.
Do multiple shadow layers hurt performance?
Static layers are cheap — the browser rasterizes the element once, however many layers it has. The real costs are animation and area: transitioning box-shadow itself repaints every frame, and giant blur radii over large elements multiply the pixels involved. Animate opacity on a pseudo-element that already carries the target shadow, and keep blurs under ~50px on big surfaces, and you'll never see it in a profiler.
What's the difference between box-shadow and drop-shadow()?
box-shadow follows the element's border box — a rectangle (with its border-radius). filter: drop-shadow() follows the rendered alpha channel, so it hugs the actual shape of a transparent PNG or SVG. drop-shadow has no spread parameter and renders on the GPU differently; use it for irregular shapes, box-shadow for cards, buttons, and anything rectangular.
How do I make shadows work in dark mode?
Don't just keep the light-mode shadow — on near-black backgrounds it's invisible. Convey elevation by lightening the raised surface (Material uses a 5–16% white overlay depending on elevation), cut your shadow alpha roughly in half for edge definition, and optionally add a subtle top inset highlight (inset 0 1px 0 rgba(255,255,255,0.06)) to simulate rim light. Preview both: this tool's background switcher exists for exactly that check.
Related tools
- Aspect Ratio CalculatorCalculate aspect ratios and missing dimensions — lock 16:9 or any ratio and solve width or height for video, images, and responsive design.
- HTML Formatter / BeautifierBeautify messy HTML with proper tag-aware indentation or minify it for production — formatted in your browser with one-click copy.
- PX ⇄ REM ConverterConvert px to rem and rem to px instantly with any root font size — plus a full conversion table and CSS tips for accessible font sizing.
- .htpasswd GeneratorGenerate .htpasswd lines for Apache and nginx basic auth — bcrypt or MD5-crypt hashes computed locally, your password never touches a server.
- Base64 ⇄ Image ConverterConvert Base64 to an image and images to Base64 data URIs in your browser — instant preview, PNG, JPG, WebP and SVG support, nothing uploaded.
- chmod Permissions CalculatorConvert Linux file permissions between octal and symbolic instantly — check rwx boxes to get chmod 755-style commands with clear explanations.