CSS Box Shadow Generator
Drag the sliders to build your shadow, watch the preview update in real time, then copy the CSS with one click. Add multiple layers for richer, more realistic effects.
Shadow drawn inside the element
Understanding the box-shadow Property
The CSS box-shadow property adds one or more drop shadows behind an element. Its full syntax is:
box-shadow: [inset] <x-offset> <y-offset> <blur-radius> <spread-radius> <color>;
| Parameter | What it does | Example |
|---|---|---|
| X Offset | Horizontal shift. Positive moves the shadow right; negative moves it left. | 4px, -8px |
| Y Offset | Vertical shift. Positive moves the shadow down; negative moves it up. | 4px, -8px |
| Blur Radius | How much the shadow is blurred. 0 gives a hard-edged shadow; higher values create a softer glow. Cannot be negative. | 0, 6px, 24px |
| Spread Radius | Expands (positive) or shrinks (negative) the shadow before blur is applied. A large positive spread creates an even glow around all sides. | 0, 4px, -4px |
| Color | Any CSS color value. Using rgba() lets you control opacity independently of the shadow's size and position, which is usually better than relying on opacity on the element itself. |
rgba(0,0,0,.2) |
| inset | Optional keyword. Moves the shadow to the inside of the element's border, creating a pressed-in or inner-glow effect. | inset 0 2px 4px … |
Multiple Shadow Layers
You can stack multiple comma-separated shadows on a single element. Layers are rendered front to back — the first value in the list appears on top. Layering lets you create subtle, realistic depth effects that a single shadow cannot produce. A common technique for material-style cards uses a tight, low-opacity shadow close to the element for the contact shadow, plus a larger, softer shadow further away to simulate ambient occlusion:
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
Another popular layering trick is to combine a colored shadow with an inset highlight to simulate soft lighting on a button:
box-shadow: 0 4px 14px rgba(99, 102, 241, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2);
Frequently Asked Questions
What's the difference between box-shadow and filter: drop-shadow()?
box-shadow always follows the rectangular bounding box of the element, even if the element has a transparent background or irregular shape. filter: drop-shadow() follows the actual painted pixels of the element — so if you have a PNG with a transparent background, drop-shadow will hug the visible shape rather than the rectangle. For most UI elements (cards, buttons, modals) box-shadow is the right choice because it's hardware-accelerated and supports spread radius and multiple layers. For images, icons, or irregularly shaped elements, filter: drop-shadow() often looks better.
Does box-shadow affect layout?
No. Shadows are drawn outside the element's layout box and do not affect the flow of surrounding elements. If you need the space occupied by a shadow to push other elements away, use outline or add extra padding/margin to the element instead. This also means overflow: hidden on a parent element will clip box shadows that extend beyond the parent's bounds.
How do I create a shadow on only one side?
Use a negative spread radius to shrink the shadow before applying a directional offset. For example, a shadow only on the bottom: box-shadow: 0 8px 6px -6px rgba(0, 0, 0, 0.4);. The -6px spread pulls in the sides so only the bottom shadow remains visible after the 8px Y offset pushes it down past the shrinkage.
Is box-shadow bad for performance?
For most uses, no. Browsers composite box-shadow on the GPU when the element is on its own compositing layer (e.g., using will-change: box-shadow or transform: translateZ(0)). If you animate a shadow, consider animating only opacity or the element's transform, and pre-render two shadow states using pseudo-elements — transitioning opacity between them is significantly cheaper than animating the shadow geometry directly.
Why does my shadow look cut off?
The most common cause is overflow: hidden on a parent or the element itself. Shadows live outside the element's painted area — any ancestor with clipping will crop them. Either remove overflow: hidden, or restructure your markup so the clipped container and the shadowed element are siblings rather than parent/child.