CSS Box Shadow Generator
Stack unlimited shadow layers with independent offset, blur, spread and inset — starting from Material and neumorphism presets or a blank slate — and export as raw CSS or a Tailwind class. Runs entirely in your browser.
Getting a Shadow That Reads as Depth, Not a Smudge
- Keep blur roughly double the vertical offset. A shadow with a big y-offset and almost no blur reads as a hard, pasted-on block instead of something floating above the surface — real light doesn't produce edges that sharp at any realistic distance.
- Turn the alpha down before reaching for less blur. Most "muddy" shadows are shaped correctly but sitting at 40–60% opacity — dropping closer to 10–20% is usually the actual fix, not softening the edges further.
- Stack two layers for anything meant to look elevated. A tight, slightly darker shadow close to the edge plus a soft, lighter one further out is how Material Design and most native OS components fake real ambient occlusion using flat CSS.
- Keep the light direction consistent across a page. If one card's shadow falls down-and-right and its neighbor's falls straight down, the layout stops reading as a coherent surface — pick one offset direction and reuse it everywhere elevation matters.
Features
Offset, Blur, and Spread Solve Different Problems
X and Y offset decide where the light appears to come from — a positive Y with zero X is a shadow falling straight down, the most common and least distracting choice for card and button elevation. Blur radius is what makes a shadow look soft rather than a solid duplicate shape sitting slightly offset from the element; the higher the blur, the further away the light source appears to be, so tight UI elements usually want a moderate blur rather than an extreme one that dissolves the shadow into nothing. Spread is the control most people skip, and it changes the shadow's size independent of its position — a small negative spread paired with a larger blur is exactly how the Large preset here avoids a shadow that looks stretched at the corners, and a positive spread is the fastest way to build a solid, hard-edged outline or focus ring without adding an actual border. A spread of 2–3px with zero blur reads as a crisp accessibility ring around a focused input; that same 2–3px with a negative sign instead is what keeps a tall button's hover shadow from visibly bulging past its rounded top and bottom edges.
Why Real Interfaces Rarely Use Just One Shadow
A single box-shadow can only approximate one physical effect at a time — either a soft ambient glow or a sharp contact shadow close to the surface, not both at once. Material Design's elevation system solves this by combining exactly two: a tighter, more opaque shadow near the element's edge standing in for light that's mostly blocked, and a second, larger, much softer one further out standing in for ambient light bouncing around a room. The Material preset here uses that same two-layer structure rather than faking the effect with one shadow at a compromise blur value, which is why it looks convincingly raised instead of just dark.
Neumorphism pushes the same idea further by using two shadows that don't even agree in color — a light one offset up-and-left and a dark one offset down-and-right, both against a background close to the element's own fill. The result reads as a shape pressed into or raised out of the surface itself rather than floating above it, which is exactly the effect the Neumorphism preset is built to demonstrate. Adjusting only the dark layer without touching the light one — or the other way around — breaks the illusion almost immediately, which is precisely why editing each layer independently matters more here than it would for a single flat shadow.
Inset Doesn't Just Point the Shadow Inward
Toggling a layer to inset moves the shadow from outside the element's border to inside it, which sounds like a small change but does real interface work: it's the standard technique for showing a button as pressed, a form field as focused, or a panel as recessed — all without adding a second element or a border. Mixing an inset layer with a normal outward layer on the same element produces the "cut into the surface but still catching light at the rim" look used on physical-feeling toggle tracks and depressed icon buttons, a combination the layer list supports directly since inset is a per-layer switch rather than a setting for the whole shadow.
Presets Are a Starting Point, Not a Final Answer
None of the nine presets are meant to be used as-is forever — they're calibrated starting values for a specific effect that would otherwise take several minutes of slider-guessing to reach from a blank layer. Loading one and then nudging blur or alpha against the live preview is consistently faster than building a layered shadow from zero, particularly for the two-layer presets, where getting the relationship between the tight and soft layer right matters more than either one's exact numbers.
The two cases are worth treating differently once tuning starts, though. A preset used untouched across a dozen buttons is a real, deliberate design decision worth keeping consistent everywhere it appears. One that's been pulled apart into a fully custom set of layers has stopped being "the Material preset" in any meaningful sense — at that point it's worth naming and storing as its own value in a token file, rather than being referenced by a preset name that no longer describes what it actually renders.
Two Export Formats for Two Different Places a Shadow Ends Up
The CSS output is the literal box-shadow declaration, comma-separated across however many layers are active, ready to paste into a stylesheet or a component's inline styles. It's the right choice whenever the shadow is headed somewhere that already has its own CSS — a design-token file, a plain stylesheet, or a component library that doesn't use Tailwind at all.
The Tailwind class wraps that exact same value as a shadow-[...] arbitrary-value utility, spaces converted to underscores the way Tailwind's syntax requires, so it works as a class name immediately without touching a config file. It's most useful mid-build, dropped straight onto a component while iterating, rather than for a value meant to live in a shared design system — for that, pairing the CSS output with a matching color reference and keeping both in one token file tends to age better than an arbitrary value scattered across markup.
From a Tuned Shadow to a Finished Component
A typical path: start from Soft or Medium for an ordinary card, Material for anything meant to feel genuinely lifted off the page, or Neumorphism for a soft-UI control — then adjust the color to match whatever's already defined in a color palette, since a shadow tinted toward a brand's ink color usually reads better than pure black. If the same element also carries a background gradient, checking it against the gradient generator's preview first avoids a shadow that gets lost against a busy backdrop. Once both the shape and the color feel right, copying the CSS straight into a stylesheet — or minifying it later with CSS Minifier once it's part of a larger file — is the entire rest of the job.