A CSS box shadow adds a shadow effect around an element's frame using the box-shadow property. A minimal working example looks like this:
.card {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
That single line pushes a soft gray shadow 4px below the element, blurred by 8px. Four numeric values control every box shadow: horizontal offset, vertical offset, blur radius, and spread radius, followed by a color. Once you know what each value does, you stop copying random snippets from Stack Overflow and start building shadows on purpose. Below, each value gets a one-line example, then five copy-paste recipes for the effects you'll actually use — soft cards, neumorphism, material design elevation, and pressed-in inputs.
The Four Values of box-shadow, Explained
The box-shadow property accepts two to four length values plus a color, per MDN's box-shadow reference. Here's what each one does:
- offset-x — moves the shadow left (negative) or right (positive).
box-shadow: 10px 0 0 gray;shifts the shadow entirely to the right. - offset-y — moves the shadow up or down.
box-shadow: 0 10px 0 gray;drops it straight below the element. - blur radius — softens the edge.
box-shadow: 0 4px 12px gray;spreads the color into a soft gradient instead of a hard line; 0 gives a crisp edge, higher values feel farther from the surface. - spread radius (optional, third length value) — grows or shrinks the shadow before blurring.
box-shadow: 0 4px 8px 4px gray;makes the shadow bigger than the element itself; negative spread shrinks it inward. - color — usually a semi-transparent black or brand color, e.g.
rgba(0, 0, 0, 0.15). Pick shadow colors visually with the SnipKit Hex Color Picker so you can dial in the exact opacity instead of guessing rgba values. - inset (optional keyword) — flips the shadow to render inside the box; covered in depth next.
The W3C CSS Backgrounds and Borders spec defines these same five parts formally, but the practical takeaway is simpler: offsets position, blur softens, spread resizes, color sets mood.
Multiple Shadows and the inset Keyword
CSS box shadow supports comma-separated lists, so one element can carry several shadows at once:
.layered {
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.24),
0 4px 12px rgba(0, 0, 0, 0.12);
}
Stacking order matters here: per MDN's box-shadow reference, the first shadow in the list renders on top of the ones listed after it. Put your tightest, darkest shadow first for a crisp edge. Your softest, lightest shadow goes last for ambient depth — the layering trick behind every realistic card effect.
Add the inset keyword and the shadow flips to the inside of the box instead of the outside:
.pressed-button {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
}
That single rule is enough to make a button look physically pressed down, which is why inset shows up constantly in inset shadow generator tools and pressed-state UI components. You can combine outer and inner shadows on the same element by separating them with a comma — a common pattern in neumorphism, covered in the next section.
Five Copy-Paste Shadow Recipes
Each recipe below is ready to paste. Tune the values live in the SnipKit Box Shadow Generator before you commit them to your stylesheet.
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
Use it when: you need a barely-there lift for list items or content cards without drawing attention to the shadow itself.
**2. Layered / realistic (3 shadows)**
```css
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.24),
0 4px 8px rgba(0, 0, 0, 0.16),
0 12px 24px rgba(0, 0, 0, 0.08);
Use it when: a modal, dropdown, or hero card needs to feel like it's physically floating above the page.
3. Neumorphism (double shadow)
background: #e0e5ec;
box-shadow: 8px 8px 16px #b8bcc2, -8px -8px 16px #ffffff;
Use it when: you're building a soft, monochrome UI where elements look molded from the same material as the background. Pair it with the SnipKit CSS Gradient Generator if you want a subtle gradient background instead of flat color.
4. Material design elevation
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
Use it when: you're following material design shadow conventions and need a recognizable "elevation level 2" card or button.
5. Inset input field
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
Use it when: a form input should look slightly recessed into the page, signaling "type here" without extra borders.
One performance note: animating box-shadow directly forces the browser to repaint on every frame, which gets janky on low-end devices. Animate the opacity of a pseudo-element carrying the shadow instead — the browser can composite that on the GPU, and the visual result is identical.
FAQ
How do I apply a shadow to only one side of an element?
A negative spread radius combined with a large offset hides the shadow on three sides. For example, box-shadow: 0 4px 4px -4px rgba(0,0,0,0.3); shows a shadow only on the bottom edge. The negative spread shrinks the shadow box, and the offset then pushes the visible part away from the other three sides.
Why is my box-shadow not showing?
Three causes account for most cases: a parent with overflow: hidden clips the shadow, a lower z-index hides it behind another element, or the shadow color blends into the background. Check overflow and z-index first. Then bump the color's alpha value in rgba to confirm the rule itself works.
box-shadow vs filter: drop-shadow() — when should I use which?
Use box-shadow for rectangular boxes since it shadows the element's frame, including corners defined by border-radius. Use filter: drop-shadow() when the element has transparency or an irregular shape. Per MDN's drop-shadow() reference, drop-shadow() follows the actual alpha shape of the content and has no spread parameter — ideal for PNG icons or SVG logos with transparent backgrounds.
Conclusion
CSS box shadow comes down to four values you now understand, plus five recipes you can paste today. Skip the manual guesswork: open the SnipKit Box Shadow Generator to preview every recipe live, drag the sliders until it matches your design, then copy the exact CSS. When your stylesheet is ready to ship, run it through the SnipKit CSS Minifier to strip the extra whitespace before deploy.
