CSS Box Shadow Generator
Build a CSS box-shadow with live preview, including layered shadows that read as one soft shadow rather than a hard edge.
Enable JavaScript to change the shadow; the CSS below is for the defaults.
Most real shadows sit directly below their element, so this is usually 0.
Roughly twice the vertical offset reads as a natural light source.
Grows or shrinks the shadow before the blur. A negative spread tucks it under the element.
A dark tint of your background reads better than pure black, which greys out colour beneath it.
Stacking smaller, darker copies is what makes a shadow look soft instead of printed on.
.your-element {
box-shadow: 0px 4px 12px rgb(11 16 32 / 0.11),
0px 1.4px 4.2px rgb(11 16 32 / 0.16);
}
Build a CSS box-shadow and watch it on a real element as you change it, including the layered shadows that read as soft rather than printed on.
How to use
- Start with the vertical offset and make the blur roughly twice it. That ratio reads as a light source above the page, which is what nearly every interface shadow is imitating.
- Leave the horizontal offset at 0 unless the design has a light source off to one side. Shadows that drift sideways look wrong next to ones that do not.
- Tint the shadow. A dark navy or a dark version of your background colour keeps colours underneath from going grey, which pure black does.
- Use a layered shadow for anything that should look raised. One shadow gives you a hard edge; two or three smaller, darker copies give you a gradient.
- Keep opacity low. Most convincing interface shadows sit between 8 and 20 percent.
Example
The same shadow, single and layered:
/* single */
box-shadow: 0px 4px 12px rgb(11 16 32 / 0.18);
/* soft two-layer */
box-shadow:
0px 4px 12px rgb(11 16 32 / 0.11),
0px 1.4px 4.2px rgb(11 16 32 / 0.16);
The second layer is smaller and slightly stronger. That is the whole trick: the near-contact shadow is tight and dark, the ambient one is wide and faint.
Pitfalls
- Pure black shadows desaturate whatever is under them. A dark tint of the background keeps the colour.
box-shadowdoes not affect layout. It never pushes anything, which is why a shadow can overlap a neighbour unexpectedly.- Large blurs are expensive to paint, particularly on a long scrolling list. Animate
transformoropacityinstead of animating the shadow. - Spread is applied before the blur, so a positive spread with a large blur quickly becomes a halo.
- An inset shadow draws inside the padding box, so it sits under the content and over the background.
- Shadows on a dark background need more opacity and less blur than the same shadow on white; copying light-mode values into dark mode is why dark interfaces often look flat.
- A shadow is not a border. At low contrast it disappears entirely for some users and in high contrast modes, so it cannot be the only thing separating two surfaces.
- Several shadows on one element paint in order: the first in the list sits on top.
Compatibility
box-shadow is supported everywhere, including the comma separated multiple shadow syntax. The rgb(r g b / a) space separated colour syntax used here needs Chrome 65, Firefox 52 or Safari 12.1; if you need older support, convert to rgba(). inset has been supported since the property shipped. The tool runs entirely in your browser.