Skip to content

[css-sizing-3] add ability to make the padding size include the border-width #7770

Open
@jonathantneal

Description

@jonathantneal

I believe CSS borders and padding would be more intuitive if borders could collapse into padding.

described below

A css-like box model which depicts margin, border, padding, and content. In the model, border is shown as being a portion of padding.



To produce consistent inner-spacing when styles include padding and border, authors must currently use tricks to collapse inner-spacing. Considering the following element with padding:

.the-card {
  padding: 4px;
}

With the default behavior, when that element receives border, the actual rendered padding appears larger than the padding that was originally set.

.the-card.with-a-bordered-variant {
  border: 1px solid;
}

In the bordered variant example above, the distance from the edge of the box to its content is now 5px.

When a designer hands over a design like that, I am usually expected to produce CSS like this:

.the-card.with-a-bordered-variant {
  border: 1px solid;
  padding: 3px;
}

I think this is tricky CSS, because the 3px padding are an implicit pre-calculation of the desired 4px padding without the 1px border.

To preserve the intent of the design, I can use custom properties and a calculation:

.the-card.with-a-bordered-variant {
  --border-width: 1px;
  --padding: 4px;
  border: var(--border-size) solid;
  padding: calc(var(--padding) - var(--border-width));
}

However, this is somewhat fragile. If --padding becomes 4px 8px then the calculation fails. I can avoid the calculation by simulating the border with an inset box shadow:

.the-design {
  --border-width: 1px;
  box-shadow: 0 0 0 var(--border-width) inset;
  padding: 4px;
}

When I implement this design and hand it over to another author, they will need to know the tricks I used to produce the intended spacing, and they may need to use the same custom property abstractions.

Ultimately, I believe authors would prefer using border if they could handle the border as part of the padding.

I do understand that border and padding are separate parts of a box, but I believe developers and designers often think about them together as a single kind of inner-spacing thing. In a similar way, I believe developers and designers think about width and height as a kind of outer-sizing thing, which is why authors can prefer box-sizing: border-box.

I recommend CSS provide something like border-collapse: padding-box or border-collapse: content-box, to allow borders to collapse into the available space of an element, just as box-sizing: border-box allows border and padding to collapse into the available size of an element.

I also believe others would benefit from this feature. Here are some example projects where the proposed behavior could alleviate the use of tricks.

Example: Dell Design System

The Dell Design System describes spacing in multiples of 4 pixels. A button is given inner spacing and outer spacing of 12px, 16px, and 20px. However, a look at the implementation shows the padding values are actually 11px, 15px, and 19px. This trick is done to account for the additional 1px of border.

Example: Hashicorp Design System

The Hashicorp Design System maintains its vertical rhythm with the same trick, omitting 1px from each side of padding. The source code includes a note regarding the pre-calculation.

Example: Carbon Design System

The Carbon Design System meticulously documents spacing as tokens. However, to achieve the intended spacing, the CSS hard-codes the offset trick for borders.

Example: Figma Design Tool

The collapsing border behavior I am advocating for is the default behavior in Figma. Until recently, it was also the only possible behavior, which would lead to issues implementing designs from Figma to the web. One comment from the issue stuck out to me:

Right now we have to build a sass function to calculate what padding values will be based on what the border value is. It adds a lot of complexity to our code across multiple applications. This may seem like a small issue but the ramifications that the borders aren’t treated the same way in Figma as they are by the browser renderer are huge for either the development team or the design team. It adds a lot of tech/design debt for the team.

While I agree with the author that Figma would need to provide an option to match current CSS behavior — and they recently did — I think the sass function is a signal that CSS is also missing some desirable behavior.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Tuesday afternoon

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions