الأدوات · CSS · مولّد ظل CSS · الأدلة · How to Build a Layered CSS Box-Shadow
How to Build a Layered CSS Box-Shadow
Box-shadow generator opens on an example card wearing this site's own two-layer shadow; Start fresh replaces it with one layer - offset 0/4px, 12px blur, no spread, black at 25% opacity - with a live CSS output below it. Every slider or colour change updates both the preview and the code at once, so there's no separate "generate" step: adjust, watch, copy.
1. Shape the first layer
Four range sliders control one shadow: Offset X and Offset Y move it sideways and down (each -50 to 50 pixels; negative Y moves the shadow above the element instead of below it), Blur softens its edge (0 to 100 pixels - 0 is a hard silhouette, higher numbers fade it out), and Spread grows or shrinks the shadow's shape independently of the element's own size (-50 to 50 pixels; negative spread pulls it in smaller than the box). A colour swatch and an opacity slider (0-100%) set the shadow's own colour, which doesn't have to be black - a soft blue or purple shadow under a card reads as a tinted ambient-light effect rather than a plain drop shadow.
The Inset checkbox flips where the shadow paints - outside the element's edge (the default, for anything meant to look raised) or inside it (for anything meant to look pressed in, like a sunken input field). It doesn't change any of the four numbers, only which side of the border they apply to.
2. Add a second layer for real depth
"Add another shadow" appends a new layer card, pre-filled as a copy of the last one so there's something reasonable to adjust rather than starting from zero. Up to four layers are allowed at once - past that, the button shows a toast naming the cap instead of silently doing nothing. Each layer keeps its own full set of controls, and the CSS output combines all of them into one real, comma-separated box-shadow value, in the order the layers are listed.
A typical two-layer depth shadow uses a small, tight, low-opacity layer for the contact point and a larger, softer, slightly-more-opaque layer for the ambient spread further out - which is exactly what the tool's own "layered" preset sets up in one click, as a starting point to adjust rather than a fixed answer.
3. Try a preset instead of starting from a blank layer
Five preset chips - subtle, soft, hard, layered, inset - replace the entire layer set with a known-good combination in one click, then stay fully editable afterward. They're a faster starting point than four sliders at their defaults, not a locked template. "Random shadow" (the main action button) does the same thing with a random pick from the same five, useful for quickly seeing a few options side by side rather than committing to the first slider guess.
4. Remove a layer, or hit the floor
Each layer card past the first carries its own "Remove this shadow" button. Removing is allowed down to one remaining layer - a box-shadow with zero layers isn't "no shadow," it's a broken value, so the tool blocks the last removal with a toast rather than letting the element end up with nothing.
Blur and spread are not the same knob
The two are easy to confuse because both make a shadow "bigger" in some sense, but they change different things. Blur softens the shadow's edge, fading it out gradually, without changing how far the shadow's darkest part extends from the element. Spread grows or shrinks the entire shape uniformly in every direction, independently of how soft or hard its edge is. A shadow with a lot of blur and zero spread is large and hazy, but starts fading the instant it leaves the element's own border. A shadow with some spread and very little blur is a genuinely bigger shape with a mostly hard edge - it grew, but it didn't get any softer. A natural-looking shadow usually wants a little of both rather than one slider pushed to its extreme, because a real shadow both grows and softens with distance from its source, not one or the other in isolation.
5. Copy the finished CSS
The output block always shows the real, current box-shadow: declaration, live, in an aria-live="polite" region so a screen reader announces the update after a change rather than mid-drag. "Copy CSS" puts the exact text on the clipboard - paste it straight into a stylesheet, and it's already correctly comma-joined across however many layers are set, in the right shorthand order every time.
Everything above runs as plain math and CSS-string building in your browser - nothing is uploaded, and there's no file involved at any point.