Toolvore

Box Shadow Generator

Design CSS box shadows visually and copy the code.

This tool runs entirely in your browser. Your data is never uploaded, never stored, and never leaves your device.

Builds a CSS drop shadow from five sliders — horizontal and vertical offset, blur, spread and opacity — plus a colour swatch and an inset toggle into one box-shadow declaration, shown live on a white card against grey.

How to use it

  1. 1Drag Horizontal offset and Vertical offset (−50 to 50px) to place the shadow, then Blur (0–100px) and Spread (−50 to 50px) to shape it.
  2. 2Choose a colour with the swatch and set Opacity separately on its own 0–1 slider, which steps in hundredths.
  3. 3Tick Inset to throw the shadow inside the box, then copy the declaration below.

Example

Input
The starting values: 4px right, 4px down, 10px blur, 0 spread, black at 0.25 opacity
Output
box-shadow: 4px 4px 10px 0px rgba(0,0,0,0.25);

The colour picker and the opacity slider are separate controls that are combined into one rgba() at the end, so the swatch always shows a fully opaque colour however faint the shadow looks. The zero spread is written out as 0px rather than omitted, and the rgba() has no spaces after its commas — both are harmless but will look different from what a formatter would produce.

What happens to your data

The colour swatch and the opacity slider never meet until the CSS string is assembled, so the alpha value exists in exactly one place — the rgba() you copy — and nowhere in the picker's own state. The preview is styled from that same string, which is why what you see and what Copy hands over cannot drift apart.

Last updated August 2026

A card sits flat against the background and you know it needs lifting, but the four numbers in a box-shadow declaration do not map onto anything you can picture. Offsets you can guess. Blur and spread are the pair people get the wrong way round, and the only reliable way to learn the difference is to move one and watch the edge change while the other stays where it was.

Decide first whether a shadow is even the right property. box-shadow traces the element's border box and its corner radius — nothing else. If the thing you want to lift is a logo with transparency, an icon or an irregular SVG, the shadow comes out as a rectangle around the picture rather than following its outline, and filter: drop-shadow() is the property that reads the alpha channel and does what you meant. It takes no spread value, which is the trade.

The second decision is one shadow or several. Real objects rarely cast a single even shadow, and the interfaces that look expensive usually stack two or three shadows in one comma-separated list: a tight, nearly opaque layer for contact, a wide faint one for ambience. What is built here is one layer at a time. Get each layer right, then paste them into a single rule separated by commas — the first in the list paints on top.

The common mistake is left over from print: pure black at heavy opacity, which reads as grey haze rather than shadow. A shadow is the surface behind it receiving less light, so tinting it toward the hue of that surface, and keeping opacity low, is usually what separates a shadow that looks placed from one that looks stuck on.

How it works

Toolvore keeps seven values in state — horizontal and vertical offset, blur, spread, opacity, a hex colour and the inset flag — and reassembles one string from them on every change. The hex is split into red, green and blue integers and recombined with the opacity slider as an rgba() colour, so the swatch and the alpha stay separate controls right to the end. That same string is handed to the preview element's inline style, which is why the white card in the grey panel is not a picture of your shadow but the shadow itself, painted by the engine that will paint your page. The weakness is that the preview is a fixed test: a small rounded square, white on light grey, at whatever size your screen renders it. A shadow judged there can look heavier on a large card, vanish on a dark background, and read differently again over a photograph, because a shadow is only ever as visible as the contrast between it and what sits behind it. The offsets stop at 50 pixels either way and blur stops at 100, so a very diffuse shadow has to be written by hand afterwards.

Common use cases

  • Lifting a card off the page without adding a border
  • Matching a shadow spec handed over from a design file
  • Learning the difference between blur and spread by eye
  • Building an inset shadow for a pressed button or an input well
  • Tuning the raised state an element takes on hover
  • Replacing a heavy shadow inherited from an old stylesheet

Frequently asked questions

What is the difference between blur and spread in a box-shadow?

Blur softens the edge; spread changes the size before any softening happens. Raise blur and the shadow keeps its footprint but fades outward from it, roughly half the blur radius spilling either side of the original edge. Raise spread and the whole shape grows in every direction, as though the element were larger, while a negative spread shrinks it. Most everyday shadows are a small offset, a moderate blur and zero spread. Spread earns its keep in two narrower jobs: a negative value to pull a wide blur back in so it does not leak past the sides, and a positive value with no blur at all, which draws a solid outline without affecting layout the way a border does.

How do I make a shadow appear on only one side?

Offset it further than you blur it, then use negative spread to pull the other edges back. For a shadow only underneath, set the horizontal offset to zero, give it a vertical offset, and set spread to a negative number close to the blur value — the shadow shrinks on every side while the downward push keeps the bottom edge visible. It is a subtraction rather than a mask, so it stays approximate: at large blur values a faint halo still escapes at the corners. If you need a genuinely clean edge on one side and nothing anywhere else, a border or a linear-gradient will do it more honestly than a shadow will.

Why is my box-shadow not showing up?

Work through these in order. The element has no dimensions, so there is nothing to cast from — an inline element with no height is the usual case. The shadow exists but a parent with overflow: hidden is clipping it. The colour is too close to the background, which happens the moment opacity drops too far on a light page. inset is switched on, so the shadow is drawn inside the box and a solid background colour paints over it. Or a later rule wins the cascade: box-shadow does not accumulate across rules, so a second declaration replaces the first rather than adding to it, and one none anywhere downstream removes the lot.

Should I use box-shadow or filter: drop-shadow?

box-shadow follows the border box and the border-radius, so it always produces a rounded rectangle however transparent the content inside happens to be. filter: drop-shadow() follows the alpha channel, which is what you want for a transparent PNG, an icon, an SVG glyph or an element with a clip-path applied. The costs are real. drop-shadow has no spread value, cannot be inset, applies to everything the element paints including its children, and is generally more expensive to render because the browser has to work out the shape before it can blur it. The argument order differs too, so a value copied from one will not drop into the other.

How do I make a shadow look soft and realistic instead of like a grey blob?

A single shadow tends to look like a sticker, because real light produces two things at once: a tight dark contact shadow where the object meets the surface, and a broad faint ambient one. The usual fix is two or three shadows in one comma-separated list — a small offset with a tiny blur at low opacity, plus a larger offset with a much wider blur at lower opacity again. Then tint them. Pure black desaturates whatever is behind it and reads as grey wash; taking the hue of the surface and darkening it gives a shadow that belongs to the page. Reduce opacity as blur rises, or the wide layer turns to fog.

Do box shadows slow a page down?

Enough to matter in the wrong place. A shadow is a blur, and blurs cost more the wider they are and the more often the browser has to recompute them. A page of static cards with modest shadows is not worth worrying about. Animating box-shadow on hover is the usual culprit, because every frame re-blurs the shape; the common workaround is to leave the shadow fixed and animate the opacity of a pseudo-element carrying a second shadow, or to animate transform and let the shadow sit still. Very large blur radii repeated across many elements, especially inside a long scrolling list, are the other case worth measuring rather than guessing at.

How should shadows work in dark mode?

Shadows work by darkening, and there is very little room to darken a background that is already dark — black on near-black is invisible, which is why interfaces that lean on elevation in light mode look flat the moment they are inverted. The convention is to stop simulating light and start signalling separation: raise the surface colour instead, so a card is a lighter grey than the page behind it, and treat any shadow as a faint accent rather than the main cue. Where you still want depth, a hairline border or a subtle inset highlight along the top edge does more than pushing opacity up, which only produces a smudge.

Is anything I do here sent anywhere or saved?

Nothing leaves the page. The seven values are ordinary component state in your browser, the CSS line is assembled from them in the same function that renders the preview, and no request goes to a server at any point — no account, no upload, no image generated elsewhere. Nothing is written to storage either, and that cuts both ways: there is no history, no undo and no saved presets, so refreshing the tab returns every control to the starting values of a 4px right, 4px down, 10px blur black shadow at a quarter opacity. Copy the declaration into your stylesheet before you close the tab, because the tool is not holding it for you.

Used in these workflows