CSS Box Shadow Generator

Generated locally in your browser. Nothing is uploaded or stored.

Generate complex CSS box shadows visually with a live preview. Stack multiple shadows, adjust colors, and copy the CSS output.

Shadow 1

0px
4px
12px
0px
20%

CSS Output

box-shadow: 0px 4px 12px 0px rgba(0,0,0,0.20);

Preview

Runs entirely in your browser — nothing is uploaded
Runs entirely in your browser. No uploads. Your files stay private.

CSS Box Shadow Generator

The CSS box-shadow property, defined in CSS Backgrounds and Borders Module Level 3, paints one or more shadows around the border edge of a box. Each shadow takes up to four length values (offset-x, offset-y, blur-radius, spread-radius), a color, and an optional inset keyword - and you can comma-separate as many of them as you like to build layered depth.
This generator builds the box-shadow string client-side using a small TypeScript helper (shadowCSS in the source above) that converts your hex colour and opacity slider into an rgba() literal and concatenates the offsets in the order CSS expects. The live preview is just a div with style={{ boxShadow: ... }} - the same string the browser's rendering engine consumes when you ship the rule, so what you see is exactly what production will paint.
The four length values do different things and getting them wrong is the most common source of ugly shadows. Offset-x and offset-y move the shadow relative to the box (positive y pushes it down, the most common direction because real-world light typically comes from above). Blur-radius is a Gaussian-style smoothing - 0 produces a hard rectangle, 12px produces a soft cloud. Spread expands or shrinks the shadow rectangle before blurring; negative spread is the trick that gives modern card shadows their tight, focused look.
Layering is where the realism comes from. Real ambient occlusion isn't a single dark blob - it's a near, sharp, low-opacity contact shadow stacked on a far, soft, diffuse glow. The Card and Layered presets here demonstrate the pattern: one shadow at y: 1, blur: 3 for the contact, another at y: 8-10, blur: 24-30 for the diffuse fall-off. Material Design's elevation system and Tailwind's shadow-md / shadow-lg utilities both follow this two-shadow recipe.
The inset keyword flips the shadow inwards so it appears inside the element rather than outside. Inset shadows are how you add convincing depth to input fields, pressed buttons, and cutaway panels. They don't mix with regular shadows on the same element by default - if you stack an inset and an outer shadow, the renderer paints both, but the inset shadow draws over the element's contents, so dark inset shadows can wash out text underneath.
Performance: box-shadow is GPU-accelerated in all modern browsers, but huge blur radii (200px+) on many elements can spike paint time on low-end Android. If you have shadows on hundreds of elements, prefer a single drop-shadow filter on a parent element, or pre-render the shadow into an SVG/PNG sprite. Animating box-shadow itself triggers a repaint every frame; animate transform: translateZ tricks or opacity instead for smooth 60fps elevation transitions.
Browser support is universal at this point - every browser since IE9 implements box-shadow without prefixes. The newer color-mix() and oklch() colour functions work inside box-shadow on Chrome 111+, Safari 16.4+, and Firefox 113+ if you want to express tints relative to a CSS custom property. For older browsers, this tool sticks to plain rgba() output, which works everywhere.

Common Use Cases

01

Material Design elevation

Build the four-tier elevation set (resting, raised, modal, dialog) with two-layer shadow stacks that match Material's spec.

02

Card hover lift

Generate a slightly larger shadow for the :hover state and animate transform: translateY(-2px) to imply the card lifting toward the user.

03

Neon glow buttons

Stack a colored shadow with high blur and 0px offset to create a soft chromatic glow around action buttons.

04

Input field depth

Use a small inset shadow at the top of an input to suggest a recessed, fillable area, mimicking native macOS form controls.

Frequently Asked Questions

Blur is the radius of the Gaussian softening - it controls how diffuse the edge becomes but doesn't change the shadow's overall size much. Spread literally adds (or with a negative value, subtracts) pixels from every edge of the shadow rectangle before the blur is applied. A negative spread + a soft blur is the formula behind tight modern card shadows.
Yes - box-shadow accepts any CSS color: named (red), hex (#ff0000), rgb(), rgba(), hsl(), hsla(), and the new color-mix()/oklch() functions in modern browsers. This generator emits rgba() because it pairs cleanly with the opacity slider, but you can hand-edit the output to use any color syntax.
Inset shadows render above the element's background but below its content, on top of borders. If your text colour is similar to the shadow colour, the shadow will visually wash it out at the edges. Either reduce opacity, shrink the blur, or add padding so the shadow stays clear of text.
Tailwind's shadow-md is two layers: 0 4px 6px -1px rgba(0,0,0,0.1) and 0 2px 4px -2px rgba(0,0,0,0.1). Punch those values into two shadow rows here, set color #000 with 10% opacity, and toggle on negative spread. The Card preset is similar in spirit.
Animating box-shadow itself causes a repaint on every frame, which is fine for short transitions but stutters on long animations or low-end mobile. The standard trick is pre-rendering both end states as separate elements and cross-fading their opacity, or animating a transform on the box and leaving the shadow static.
Yes for the outer shadow - it casts based on the element's box, not its content. But inset shadows on a transparent element only show where the element has visible background, which can produce surprising results. Set a background-color (even rgba(0,0,0,0.0001)) if you need consistent inset rendering.
Spec-wise there's no limit, but each layer is a paint pass. In practice three or four layers is the realism ceiling - more rarely improves the look and starts to chew into paint budget. The presets here use 1-2 layers, which covers 95% of design needs.
If a parent has overflow: hidden or overflow: clip, child shadows get clipped at the parent's padding box. Either remove the overflow rule, use overflow: visible explicitly, or move the shadowed element out of the clipping ancestor.
box-shadow follows the element's rectangular border edge, ignoring transparency in its content. filter: drop-shadow follows the actual painted pixels, so it casts a shadow around opaque parts of an image or text. Drop-shadow is heavier to compute but right for irregular shapes.
No - box-shadow length values must be in absolute units (px, em, rem, etc.) or 0. Percentages are not allowed. If you need responsive shadows, use rem and let the user's root font size scale the values, or scale the entire component with transform.

Advertisement