[csswg-drafts] block-step-size doesn't actually work (#11514)

tabatkins has just created a new issue for https://github.com/w3c/csswg-drafts:

== block-step-size doesn't actually work ==
Sorry for the lateness of this feedback, but the discussion yesterday got me and @bfgeek talking about the property.

As far as either of us can tell, `block-step-size` simply doesn't work as intended, and fundamentally *can't*, due to collapsing margins. The examples in the spec avoid this problem because they just... aren't using margins in a way that triggers collapse.

(Note, these examples depend on today's resolution to make `block-step-size` inherit, but that's not important for what's happening. It would be identical if you manually specified the property on everything you want to be aligned.)

As specified, block-step-size causes the box's *outer size* to round to the specified step size. The spec also says that you ignore margin collapsing for this purpose; you round considering the margins as *uncollapsed*, then whatever happens happens.

So, consider this example:

```html
<body style="block-step-size: 30px">
 <div id=one style="margin-top: 20px">
  <div id=two style="margin-top: 40px">
   <div id=three style="height: 10px;"></div>
  </div>
 </div>
```

#three starts with 10px of content, so it gains 20px of margin, 10px each to top and bottom, to become 30px tall.

#two starts with 40px of margin and 10px of content, so it gains 10px of margin, 5px each to top and bottom, to become 60px tall.

#one has 20px of margin and 10px of content, so it does nothing; it's already aligned at 30px tall.

This results in this equivalent markup:

```html
<body>
 <div id=one style="margin-top: 20px;">
  <div id=two style="margin-top: 45px; margin-bottom: 5px;">
   <div id=three style="margin-top: 10px; margin-bottom: 10px; height: 10px;"></div>
  </div>
 </div>
```

Ideally, this means that each element's outer size lines up with a 30px grid. However, *all of these margins collapse*. Thus, post-collapse, it's *actually* equivalent to:

```html
<body>
 <div id=one style="margin-top: 45px; margin-bottom: 10px;">
  <div id=two style="">
   <div id=three style="height: 10px"></div>
  </div>
 </div>
```

And with this, *none* of the items are aligned! #one is 65px tall; #two and #three are both just 10px tall. If there was text in the example that depended on these elements being a multiple of 30px tall, it would completely fail to be aligned.

------

Here's a different example, even simpler (no margins at all in the actual markup!), but still failing due to *sibling* margin collapse:

```html
<body style="line-height: 20px; block-step-size: 1lh; columns: 2;">
 some text
 <div style="height: 10px"></div>
 <div style="height: 10px"></div>
 more text
 <hr style="break-after: column;">
 first line
 second line
 third line
 fourth line
```

The intention is clearly that the text on the two columns lines up; in particular, the "more text" in the first column and "fourth line" in the second column should be aligned.

That doesn't happen, tho. The two divs are each 10px tall, so they gain 10px of margin, 5px each to top and bottom. The 5px bottom margin of the first then *collapses* with the 5px top margin of the second, meaning they're only 5px apart; the combined height of their outer boxes is only 35px, not 40. So, "more text" is misaligned by 5px from "fourth line", as would be any additional text in the columns.

------

The conclusion we've been forced to draw is that `block-step-size` just fails to work *at all* unless the elements it's applying to just happen to never collapse margins at all. Given the core use-case is aligning text, and default paragraph styling (and the styling of lists, blockquotes, details, etc...) depends on collapsing margins, that doesn't seem likely to happen very often. So, *almost all of the time*, elements fail to line up with the implied block-step-size grid, and text fails to align across columns, contrary to the property's explicit aims. Even if `block-step-insert` puts the extra space in the padding or content boxes, if the elements already had a collapsing margin it still fails to align them.

The example in the spec seems to be carefully designed to not trigger these issues, making the property appear to work:

![Figure 3 in the spec](https://drafts.csswg.org/css-rhythm-1/images/block-step-size-after.png)

The paragraphs in the text don't use margins, instead relying on `text-indent` to create their visual separation. The elements that get extra margin from `block-step-size` (a heading, an image, two blockquotes) all happen to be separated from each other, with their neighboring elements not using margins. As a result, zero margin collapse happens anywhere, all the step-sized items end up the expected size, and the text aligns properly across columns.

We're not entirely sure where to go from here. We don't think Chrome should implement the property as specified, and don't see any easy fixes to make it worth implementing. We *suspect* that the only reasonable way forward is to continue with Line Grid, figure out a way past its issues, and do `box-snap` instead (presumably with the increased controls that `block-step` has grown).

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/11514 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Thursday, 16 January 2025 16:39:28 UTC