Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-sizing-3] border-collapse: padding-box #7770

Open
jonathantneal opened this issue Sep 20, 2022 · 4 comments
Open

[css-sizing-3] border-collapse: padding-box #7770

jonathantneal opened this issue Sep 20, 2022 · 4 comments

Comments

@jonathantneal
Copy link
Contributor

jonathantneal commented Sep 20, 2022

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.

@markacianfrani
Copy link

There's a strong need for this in the Design Token space. When it comes to spacing tokens, you need to draw straws for who has to do the calc/hack.

Some design systems like Paste resort to using shadow tokens for borders:

other box shadow tokens are duplicates of border tokens and are used to visually add a border without affecting the height of the component

@bfgeek
Copy link

bfgeek commented Sep 21, 2022

One thing to note & explore is that the "css box-model" also potentially has scrollbar insets between the border insets, and the padding insets. How does this behave when scrollbars are present?

@fantasai
Copy link
Collaborator

Would this need a separate property, or could we fold this into box-sizing as like a border-in-padding keyword or something like that? (Preferably with a less awkward name, though.)

@tabatkins
Copy link
Member

I think this should be a separate property. box-sizing already controls one thing well - which box is sized by width/height. This is a new ability that's vaguely thematically related (making it easier to keep boxes the same size), but doing something rather different, and which might want additional controls (like something around scrollbars).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants