CSS box shadow generator

Design box shadows with live sliders for offset, blur, spread and opacity — including inset shadows — then copy the CSS.

CSS Box Shadow Generator

Design custom box shadows with visual sliders. Adjust offset, blur, spread, and colour for the perfect shadow effect.

#000000

Live Preview

Your Shadow
CSS Code

How to use this tool

The box-shadow property takes its values in a fixed order, and knowing what each one does turns guesswork into intent:

Horizontal offset moves the shadow right (positive) or left (negative). Vertical offset moves it down or up. Blur radius controls how soft the edge is — 0 gives a hard-edged shape, higher values diffuse it. Spread grows or shrinks the shadow before blurring, which is the value most people forget exists. Colour finishes it, and is almost always best expressed with alpha transparency.

Add inset at the start and the shadow is drawn inside the element instead of outside — the standard way to make a field look recessed or a button look pressed.

Why realistic shadows use low opacity and large blur

The single biggest giveaway of an amateur shadow is opacity that is too high. Real shadows in the physical world are diffuse and subtle; a shadow at 50% black looks like a sticker, not depth. Professional interfaces overwhelmingly use something in the range of 8–25% opacity with a generous blur.

The second giveaway is a shadow with no vertical offset. Light in almost every interface is implicitly from above, so shadows should sit slightly below their element. A shadow offset only horizontally reads as wrong even to people who cannot articulate why.

Layering shadows for real depth

The technique that separates polished UI from flat UI is stacking multiple shadows in a single declaration, separated by commas. Physical objects cast both a tight, darker contact shadow right at their base and a wider, softer ambient shadow further out. Simulating both is far more convincing than one shadow trying to do everything:

box-shadow: 0 1px 2px rgba(0,0,0,0.08), 0 8px 24px rgba(0,0,0,0.12);

Build an elevation scale from this idea — a small shadow for resting cards, a medium one for hover, a large one for modals — and apply it consistently. Consistent elevation is what makes an interface feel like a coherent system rather than a collection of screens.

Shadows, performance and dark mode

Box shadows are cheap to paint but not free, and animating them can cause repaints on every frame. If you want a lift-on-hover effect, transition transform for the movement and keep the shadow change modest — or pre-render two shadow states and cross-fade a pseudo-element, which stays on the compositor.

Dark interfaces need a different approach entirely. A black shadow on a dark background is nearly invisible, so depth has to come from elsewhere: a subtle light border on the top edge, a slightly lighter surface colour, or a coloured glow that matches your accent. That is why this site uses rim highlights and soft coloured glows rather than heavy drop shadows.

Developer Implementation Guide: Programmatic Shadow Layering

Beautiful, natural-looking shadows in UI design are rarely achieved with a single drop shadow. In the real world, light diffuses. To recreate this in CSS, designers layer multiple shadows on top of each other, starting from a small, dark shadow (ambient occlusion) out to a large, faint shadow (diffused light).

The Mathematics of Smooth Shadows

If you are building a design system component library in JavaScript, you can generate these layered shadows algorithmically based on a single "elevation" parameter.


function generateElevation(level) {
  // level is typically between 1 and 5
  if (level < 1 || level > 5) return 'none';
  
  const y1 = level;
  const blur1 = level * 2;
  const alpha1 = 0.1 + (level * 0.01); // Slightly darker inner shadow
  
  const y2 = level * 3;
  const blur2 = level * 6;
  const alpha2 = 0.05 + (level * 0.01); // Fainter outer diffusion
  
  return 
    0px px px rgba(0,0,0,),
    0px px px rgba(0,0,0,)
  .trim();
}

// Example usage:
document.getElementById('card').style.boxShadow = generateElevation(3);
// Output: 0px 3px 6px rgba(0,0,0,0.13), 0px 9px 18px rgba(0,0,0,0.08)
        

By defining your shadows through an algorithm like this, you guarantee that all elevated components in your application share the same simulated light source, resulting in a cohesive and premium aesthetic.

Frequently asked questions

What do the box-shadow values mean?

In order: horizontal offset, vertical offset, blur radius, spread radius, then colour. Add the inset keyword at the start to draw the shadow inside the element instead of outside it.

How do I make a subtle, realistic shadow?

Use low opacity (roughly 8–25%), a generous blur, and a small positive vertical offset so the shadow sits below the element. High-opacity shadows with no offset are the most common cause of shadows looking fake.

Can I add more than one shadow to an element?

Yes — separate multiple shadows with commas. Layering a tight contact shadow with a wider ambient one produces far more convincing depth than a single shadow, and it is how most design systems build their elevation scales.

How should shadows work in dark mode?

Black shadows barely register on dark backgrounds. Convey depth instead with a lighter surface colour, a subtle top border highlight, or a soft coloured glow matching your accent colour.