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

block-step-size doesn't actually work #11514

Open
tabatkins opened this issue Jan 16, 2025 · 3 comments
Open

block-step-size doesn't actually work #11514

tabatkins opened this issue Jan 16, 2025 · 3 comments

Comments

@tabatkins
Copy link
Member

tabatkins commented Jan 16, 2025

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:

<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.

(It's possible #one and #two should count their children's sizes differently, somehow taking child margins into account. That will just give different erroneous results, tho, since the children definitely won't end up that size after margins have collapsed either.)

This results in this equivalent markup:

<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:

<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:

<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

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).

@Loirooriol
Copy link
Contributor

these examples depend on today's resolution to make block-step-size inherit

Wait, what? #1902 was resolved to close no change, so it doesn't inherit.

We're not entirely sure where to go from here.

What if a non-none block-step-size inhibits margin collapsing?

@bfgeek
Copy link

bfgeek commented Jan 16, 2025

What if a non-none block-step-size inhibits margin collapsing?

IMO that'd break a lot of things, (e.g. applying block-step-size shouldn't mean that you need to fundamentally rework your style for that subtree). Margin-collapsing (as annoying as it is to implement) is quite desirable in block-layout as it provides a substitute for gap.

@tabatkins
Copy link
Member Author

Wait, what? #1902 was resolved to close no change, so it doesn't inherit.

Ah, slip of the mind. Like I said tho, doesn't actually matter for the examples.

What if a non-none block-step-size inhibits margin collapsing?

Yeah I thought of that too, but discarded it for the reason Ian provides. Thus "no easy fix we can see" :(

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

3 participants