Skip to content
Back

CSS Borders Are Getting Easier

What has changed in Figma and CSS borders, and which workarounds are becoming unnecessary.

I have written about my problem with CSS borders before. It started with a fancy button: 160 × 48 pixels, a 16-pixel radius, a 1-pixel gradient border and a small inner shadow. Quick to build in Figma. A few more layers than expected in the browser.

Some of that is getting easier. Figma has brought its Auto Layout calculations closer to CSS. Chromium supports background-clip: border-area. Two changes in different places that come together in the same button.

Figma Calculates More Like CSS

The new version of Auto Layout includes inside strokes in layout calculations by default. The border gets its own space outside the padding. For a frame with Included borders, CSS padding and Figma padding now describe the same spacing.

A 20 px line of text, 13 px of padding above and below, plus a 1 px border on each side. That adds up to 48 px. No subtracting the border from the padding afterward.

.button {
  box-sizing: border-box;
  min-width: 160px;
  border-radius: 16px;
  line-height: 20px;
  padding: 13px 16px;
  border: 1px solid currentColor;
}

With Hug contents, the component grows with its content. With a fixed height, the border takes up space within that height. Just as you would expect in a browser.

Included Is Now the Default

The default and other details of the calculation have changed. Center and outside strokes do not count toward layout. A frame's stroke setting no longer affects its children. Padding is treated as a minimum amount of space. Figma's overview of the new Auto Layout explains the individual changes.

Existing frames do not switch automatically. Check which layout version and border mode the frame uses. Excluded still makes sense when an edge is meant to sit over the content. A card with overlapping borders does not need rebuilding just because the default has changed.

And There Is Still the Gradient

A rounded gradient border can be built with two background layers or a mask. One method covers the center. The other cuts it out.

With background-clip: border-area, the background can be limited directly to the border area. The gradient stays at the edge. The center stays clear. The radius works too.

.button {
  border: 1px solid #6b4eff;
  border-radius: 16px;
}

@supports (background-clip: border-area) {
  .button {
    border-color: transparent;
    background: linear-gradient(135deg, #d94f30, #6b4eff);
    background-origin: border-box;
    background-clip: border-area;
  }
}

No pseudo-element, no mask-composite operation, no white surface covering the gradient. That is particularly useful over images or other changing backgrounds.

border-color still does not accept gradients. The gradient remains a background whose painting area is limited to the border. The border itself is transparent so the gradient can show through.

Browser Support

Chrome supports border-area from version 150. Safari has supported it since 18.2. The feature is not entirely new. Chromium makes it available to more users.

Firefox is still missing support. That is why the example starts with a solid border. Only inside @supports does it become transparent and receive the gradient. Same dimensions, different paint.

If the gradient needs to look the same everywhere, the mask technique remains an option as a fallback. If the center needs its own fill, that requires another background layer.

What This Does Not Solve

border-area changes how the background is painted. The border still takes up layout space. An inside stroke over an image does not automatically become a matching CSS border. An overlay and the box model are still two different things.

I would also keep looking closely at inner shadows. The new layout calculation does not, by itself, tell us where the shadow begins. The difference in shadow placement is not automatically resolved.

And old files are still old files. The new calculation only helps once the component actually uses it.

What This Means for Agents

Dev Mode and MCP provide values. The closer the underlying models are, the less translation is needed during implementation. That helps developers and, in my view, agents too.

This does not tell us whether Figma made the change specifically for agents. The practical benefit remains: fewer special cases for padding and borders, fewer helper layers for a gradient border.

An agent still needs to know whether the frame uses Included or Excluded borders and which browsers the site needs to support. That information is not contained in the border color alone.

Conclusion

The button looks the same in the end. Building it gets easier.

Figma provides a better-matched layout model. CSS offers a more direct way to create a gradient border. Workarounds do not disappear everywhere, but they become less necessary. And that is how it should be. A border should not be a small project of its own.

My Problem with CSS BordersoutdatedHow Figma and CSS handle borders, and where they differ.