Open jonathantneal opened 2 years ago
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
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?
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.)
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).
The CSS Working Group just discussed [css-sizing-3] border-collapse: padding-box
, and agreed to the following:
RESOLVED: Add a control for making padding size include border-width (and scrollbar width); ask for feedback on its relationship to box-sizing
To get more info on use cases, I asked a designer I know working on a popular design system and this is what they had to say:
Interesting... We do use calculations for consistent form control heights, which incidentally accomplishes what this issue is asking for. I do see the use case, though an inset
box-shadow
seems to cover this concept already from my POV. If I had, say, a typically borderless card, but I wanted to emphasize it with a border and keep all other proportions the same, I'd turn tobox-shadow
.
At first when this issue came up, I (alongside many other participants) were puzzled about use cases, but this is something I’ve encountered many times as well, and indeed, ideally people should not have to resort to hacks like box-shadow
.
If use cases are similar to this one, it does seem like the border width should be subtracted from the padding, and not the other way around.
@jonathantneal We discussed the idea and decided to adopt it, but we have an open question: Should this switch be
box-sizing
(thus always set together with box-sizing
)?box-sizing
(thus always cascading independently)?box-sizing
, e.g. add box-sizing-size: border-box | content-box
and box-sizing-padding: padding | border-padding
and allow the newly shorthanded box-sizing
to also take the border-padding
keyword (so they can be set independently or together)?We're interested in hearing the pros and cons of each approach and how well they fit with the way this is likely to get used by authors. :)
I was wondering whether there has been any progress on this proposal.
In several recent projects, I have encountered this issue requiring workarounds a few times, using the following box-shadow and custom properties methods as described above, to effectively manage the collapsing of inner spacing and padding i.e. button and card components.
I would love to see this CSS feature become available across all browsers.
For fallback purposes, I wonder if it should be an opt-in keyword in the border-with
(and its longhands), so that if you try to change the width of the border without affecting the size of the box, if you're not in a browser that knows about this opt-in, it fails to change the border size and thus succeeds at preserving the box's size.
In any case, it'll be possible to @supports
your way through this and have conditional styles, but if you don't go through that, what's more important in a legacy UA: respecting the desired border size, or respecting the lack of impact on the box's overall size?
I believe CSS borders and padding would be more intuitive if borders could collapse into 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:
With the default behavior, when that element receives border, the actual rendered padding appears larger than the padding that was originally set.
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:
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:
However, this is somewhat fragile. If
--padding
becomes4px 8px
then the calculation fails. I can avoid the calculation by simulating the border with an inset box shadow: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
andheight
as a kind of outer-sizing thing, which is why authors can preferbox-sizing: border-box
.I recommend CSS provide something like
border-collapse: padding-box
orborder-collapse: content-box
, to allow borders to collapse into the available space of an element, just asbox-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:
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.