CSS box shadow generator.

Set offset, blur, spread, color, and inset. Copy the box-shadow CSS or a Tailwind shadow class.

CSS · Tailwind
Explore the toolbox
Horizontal offset0px
Vertical offset20px
Blur207px
Spread10px
box-shadow: 0px 20px 207px 10px rgba(165, 39, 255, 0.48);

Gradient glow shadows

How to use the CSS box shadow generator

This tool builds a single box-shadow from five values: horizontal offset, vertical offset, blur, spread and color, plus an inset switch. You can preview it on a dark or light tile and copy it as a CSS declaration or a Tailwind CSS v4 class. Below the generator is a set of gradient glow cards, which use a different technique. The notes here explain what each value does, how to stack shadows, and where shadows fall short.

What each control changes

The output follows the order of the box-shadow syntax: optional inset, x offset, y offset, blur radius, spread radius, then color. The tool's default, 0px 20px 207px 10px rgba(165, 39, 255, 0.48), is a wide violet glow pushed slightly downward.

  • Horizontal and Vertical offset (−100 to 100px) move the shadow. Positive values go right and down, which matches light coming from the top left.
  • Blur (0 to 300px) softens the edge. At 0 the shadow is a hard-edged copy of the box; larger values spread the fade over a wider area.
  • Spread (−50 to 100px) grows or shrinks the shadow before it is blurred. A negative spread with a positive y offset keeps the shadow under the element instead of around it.
  • Shadow color takes any color with alpha. Shadows look more natural at low opacity and slightly tinted toward the background or brand color than in pure black.
  • Inset draws the shadow inside the box, which suits pressed buttons, input fields and wells.

CSS and Tailwind output

The CSS tab returns one box-shadow declaration. The Tailwind tab returns a shadow-[…] arbitrary value with underscores in place of spaces, since class names cannot contain spaces. Randomize picks new offsets, blur, spread and color; the reset button returns to the default.

In Tailwind v4, an arbitrary shadow writes its color as a fallback inside var(--tw-shadow-color, …). That means a color utility such as shadow-violet-500/50 on the same element replaces the color while keeping your offsets and blur, and ring utilities still combine with it because Tailwind composes rings and shadows into one box-shadow.

html
<!-- CSS tab -->
<style>
  .card { box-shadow: 0px 20px 60px -10px rgba(165, 39, 255, 0.48); }
</style>

<!-- Tailwind tab, recolored with a shadow color utility -->
<div class="rounded-2xl bg-zinc-900 shadow-[0px_20px_60px_-10px_rgba(165,39,255,0.48)] shadow-sky-500/40">
  ...
</div>

Stacking several shadows

This tool makes one shadow. To stack several, join box-shadow values with commas in CSS, or inside the brackets of the Tailwind class. Layering is how most realistic elevation is built: a small, tight, darker shadow anchors the element to the surface, and a larger, softer, lighter one suggests height. Generate each layer here, then combine them. The first shadow in the list is drawn on top.

css
.card {
  box-shadow:
    0 1px 2px rgba(15, 23, 42, 0.10),
    0 8px 24px rgba(15, 23, 42, 0.12);
}

/* Tailwind v4 */
/* shadow-[0_1px_2px_rgba(15,23,42,0.10),0_8px_24px_rgba(15,23,42,0.12)] */

The gradient glow cards

The glow examples below the generator are not box-shadow. A box-shadow has a single color, so a multicolor glow needs a separate element: a gradient layer positioned slightly outside the card (absolute -inset-2), blurred with blur-2xl (40px in Tailwind v4) and set to half opacity, with the card placed on top. Each example copies as Tailwind JSX.

Keep the outer wrapper relative so the glow stays attached to the card, and keep the card itself relative so it paints above the glow. The glow extends past the card, so a parent with overflow-hidden will cut it off.

jsx
<div className="relative">
  <div className="absolute -inset-2 rounded-lg bg-linear-to-r from-fuchsia-500 to-cyan-400 opacity-50 blur-2xl" />
  <div className="relative rounded-lg border border-zinc-700 bg-zinc-900 p-8 text-slate-300">
    Card content
  </div>
</div>

Where shadows fall short

Shadows almost disappear on dark backgrounds, which is why the preview has a Light and Dark switch. On dark interfaces, a faint light border or ring, or a colored glow, usually communicates depth better than a black shadow.

Do not rely on a shadow alone to show where a button or input is, or which element has focus. WCAG 2.1 asks for 3:1 contrast for the visual boundaries people need to identify a control, and in Windows High Contrast and other forced colors modes browsers drop box-shadow entirely. Use a border or an outline for anything functional and keep the shadow decorative.

Very large blur radii cost more to paint, and animating box-shadow repaints it on every frame. For a hover lift, put the larger shadow on a ::after pseudo-element and transition its opacity instead. Shadows also do not take up space in the layout and are clipped by any ancestor with overflow hidden, which is the usual reason a shadow appears cut off.

Questions

How do I add a box shadow in Tailwind CSS v4?
Use a preset such as shadow-sm, shadow-md or shadow-lg, or an arbitrary value like shadow-[0_8px_24px_rgba(0,0,0,0.12)]. Note that v4 renamed the small presets: the old shadow-sm is now shadow-xs, and the old bare shadow is now shadow-sm.
How do I put a shadow only on the bottom of an element?
Combine a positive vertical offset with a negative spread about equal to the blur, for example box-shadow: 0 8px 6px -6px rgba(0, 0, 0, 0.3). The negative spread pulls the shadow in at the sides so only the bottom edge shows.
How do I make an inset shadow in Tailwind v4?
Turn on Inset and copy the class: shadow-[inset_0px_2px_6px_0px_rgba(0,0,0,0.3)] works in v4. Tailwind v4 also has separate inset-shadow-* utilities, which can sit on the same element as an outer shadow-* class.
What is the difference between box-shadow and drop-shadow()?
box-shadow follows the element's box and border-radius, and supports spread, inset and multiple layers. filter: drop-shadow() follows the visible pixels, so it traces the outline of a transparent PNG or an SVG shape, but it has no spread or inset value.

Updated