CSS box-shadow to Figma Effect: The Property by Property Map

A CSS box-shadow value and a Figma Drop Shadow or Inner Shadow effect hold the same five properties under different names. Here is the field by field map.

REFERENCEDESIGNERPublished

Answering the question up front

A CSS box-shadow and a Figma Drop Shadow or Inner Shadow effect describe the same shadow. Same five values: an X offset, a Y offset, a blur amount, a spread amount, and a color, just under different field names. One CSS keyword doesn't get its own field in Figma at all: inset. It maps to picking a different effect type instead.

This is a reference piece, so skim the property map below and come back for the two places the mapping actually breaks: Figma's spread restriction, and what happens to a shadow on a text layer.

The box-shadow syntax, field by field

CSS defines box-shadow as a comma-separated list of shadows, each one built from up to six parts: offset-x, offset-y, an optional blur-radius, an optional spread-radius, an optional color, and an optional inset keyword. MDN's box-shadow reference lays out the required and optional parts this way, and the W3C CSS Backgrounds and Borders spec is the formal source for the same six-part model.

Only offset-x and offset-y are required. Skip blur-radius and it defaults to 0: a hard edged shadow with no feathering. Skip spread-radius and it also defaults to 0, so the shadow box matches the element's own box exactly. Skip color and the shadow inherits the element's own color value, which is rarely what you want, so set it explicitly.

A typical card shadow reads like this:

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

That's offset-x: 0, offset-y: 4px, blur-radius: 12px, spread-radius: 0, and a black fill at 15% opacity. A recessed input field, by contrast, adds the inset keyword:

box-shadow: inset 0 1px 3px 0 rgba(0, 0, 0, 0.2);

Same five values, but now the shadow paints inside the box instead of outside it.

box-shadow takes a comma-separated list, so one property can hold several shadows stacked on top of each other. A common pattern layers a tight, dark shadow for definition with a soft, faint one for ambient depth:

box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.3), 0 8px 24px 0 rgba(0, 0, 0, 0.1);

The first shadow listed renders on top, the last one renders at the back, and each shadow in the list is otherwise fully independent: its own offsets, its own blur, its own spread, its own color.

What a Figma shadow effect actually holds

Figma's effects panel gives a Drop Shadow or Inner Shadow effect five adjustable fields: X, Y, Blur, Spread, and Fill. Figma's own help center article on applying effects describes X and Y together as setting the direction of the light source, Blur as controlling how soft or sharp the shadow's edge is, Spread as adjusting how large the shadow reads relative to the layer, and Fill as the paint and opacity applied to the shadow itself.

That same article states plainly that both shadow effects translate to the box-shadow property in CSS. One exception is worth remembering: a shadow effect on a text layer translates to text-shadow instead, not box-shadow, even though the effect panel you use to set it looks identical either way.

Inner Shadow behaves like Drop Shadow in every field, but paints inside the layer's boundary instead of outside it. Designers reach for it on a recessed panel or a pressed button state.

Take the card shadow from the previous section, 0 4px 12px 0 rgba(0, 0, 0, 0.15). On a Figma layer that becomes a Drop Shadow effect with X set to 0, Y set to 4, Blur set to 12, Spread set to 0, and Fill set to black at 15% opacity. Every number carries straight across; only the field names change.

The property map, side by side

Reading one against the other, the fields line up almost one to one:

CSS box-shadowFigma effect fieldNotes
offset-xXSame sign convention: negative moves the shadow left.
offset-yYNegative moves the shadow up.
blur-radiusBlurDefaults to 0 in CSS if omitted; Figma always shows a value.
spread-radiusSpreadSee the shape restriction below, this is where the map gets uneven.
colorFillFigma splits color and opacity into separate controls under Fill.
inset keywordEffect typeNot a field. Choosing Inner Shadow instead of Drop Shadow is the equivalent of adding inset.

The last row is the one people miss. There's no inset checkbox sitting next to Blur and Spread. The choice gets made once, at the top of the effect, by picking which of the two effect types you add to the layer.

Where the mapping breaks down

Spread has a shape restriction in Figma that CSS does not have

CSS spread-radius works on any box: a div, a button, an a tag, anything with a box model. Figma's Spread field is narrower. It only affects rectangles, ellipses, frames, and components, and even on those it requires clip content to be turned on with the layer's fill opacity at 1% or higher. A shadow that reads correctly in the browser can come in flatter in Figma if the source layer doesn't meet that condition, so it's worth checking spread values on anything imported from an odd element type.

In practice that means a shadow with real spread, say box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.5), a common focus ring pattern, needs its target layer to already be a rectangle, ellipse, frame, or component with clip content on before the Spread field does anything. On a layer type outside that list, the Spread value has nowhere to apply, and the ring effectively collapses to Blur alone.

Multiple shadows keep their order, but check it

A comma-separated box-shadow list becomes a stacked list of effects on the same Figma layer, in the same order: first listed, first on top. Clean mapping, but easy to misread visually if a shadow with a small offset sits under a shadow with a large one. When in doubt, compare the effects list top to bottom against the CSS declaration left to right.

Text shadows are a different property entirely

Worth repeating on its own: a shadow on a text node comes out as text-shadow in CSS, never box-shadow, regardless of how it looks in Figma's effects panel. If you're reading a stylesheet against a Figma file and the numbers don't match on a text layer, this is usually why. Treat text shadows as their own mapping, not a variant of this one.

Where this fits in the CSS-to-Figma property map

This sits alongside a few other property-by-property references worth bookmarking together: how CSS flexbox maps to Figma auto-layout, what survives when CSS grid converts to Figma layers, and how each CSS position value shows up in Figma.

UnHTML imports a page's actual CSS rather than working from a screenshot, so this shadow mapping is what lands in a Figma file on import, field for field, not an approximation of it.

Takeaway

Five CSS values, five Figma fields, and one keyword, inset, that becomes a choice of effect type instead of a field of its own. The two places this breaks are Spread's shape restriction and text layers, which use text-shadow instead of box-shadow no matter what the effects panel looks like. Bookmark the property map table above. It's the part worth coming back to.

Questions

Does box-shadow's inset keyword have a matching field in Figma?
No, there is no separate inset toggle on one effect. Inset maps to picking Inner Shadow as the effect type instead of Drop Shadow. Everything else, X, Y, Blur, Spread, and Fill, works the same on both effect types.
What happens to multiple comma-separated box-shadow values?
Each shadow in the comma-separated list becomes its own entry in Figma's effects list on that layer, stacked in the same order: the first shadow listed in CSS sits on top in Figma too.
Does Figma's spread field work the same way everywhere?
Not quite. CSS spread-radius works on any box. Figma's Spread field only affects rectangles, ellipses, frames, and components, and it requires clip content turned on with the layer's fill opacity at 1% or higher.
Can a text shadow use the same mapping?
No. A shadow on a text layer becomes text-shadow in CSS, not box-shadow, even though the effect panel in Figma looks the same. Treat text shadows as a separate property.