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-multicol] Margin collapsing does not make sense with column-spans. #2203

Closed
neerjapancholi opened this issue Jan 19, 2018 · 13 comments

Comments

@neerjapancholi
Copy link

commented Jan 19, 2018

I'm filing this based on a discussion I just had with @dbaron.

It seems like the multicol spec does not forbid margin collapsing with column-span elements. So the margin of a column-span can collapse w.r.t. just one column and that doesn't make sense. Also, the spec mentions that a multicol element itself creates a BFC but does not specifically say that the columns inside it also create a BFC. This might clarify the margin collapsing behavior for column-spans.

An example of an existing test where this can be seen is -
https://github.com/w3c/web-platform-tests/blob/master/css/css-multicol/multicol-span-all-margin-bottom-001.xht

Screenshots of Chrome - (Orange and black bands are the column-spans)
screen shot 2018-01-18 at 4 30 16 pm

@dbaron

This comment has been minimized.

Copy link
Member

commented Jan 19, 2018

The other piece about the columns themselves not being BFCs (and only the multicol container establishing a BFC) is that technically, the way the spec is worded, a float in the second column has to have its top below the tops of all the floats in the first column (etc., for all the other float rules).

But I think it's somewhat nonsensical for margins to collapse between something in a column and something that's column-spanning; it's also not clear where the resulting collapsed margin would end up.

@FremyCompany

This comment has been minimized.

Copy link
Contributor

commented Jan 22, 2018

I am not entirely sure the proposed update makes sense. If you have an heading instead of an Orange box, you clearly would not want its top margin not to merge with the spanner bottom margin (this should be true for all columns, not just the first one).

My understanding is that whatever margin is set on the spanner should get deduced of the margin required to be applied on the first element of each column. That seems to be the useful behavior here.

@rachelandrew rachelandrew added this to Unfiled in css-multicol-1 May 27, 2018
@rachelandrew rachelandrew self-assigned this Oct 10, 2018
@rachelandrew rachelandrew moved this from Unfiled to Needs action in css-multicol-1 Oct 10, 2018
@rachelandrew rachelandrew moved this from Needs action to Needs discussion in css-multicol-1 Oct 10, 2018
@rachelandrew

This comment has been minimized.

Copy link
Contributor

commented Oct 10, 2018

Resolved in #2582 is that column boxes do create a BFC and spanners are BFCs that collapse margins. However @mstensho had some outstanding queries on that resolution. I'll add this to the F2F discussion, but if anyone wants to add anything on either of those here that would be great.

@aethanyc

This comment has been minimized.

Copy link

commented Oct 10, 2018

The proposed change to the test reference mentioned in the first comment has been made in web-platform-tests/wpt#13395

@mstensho

This comment has been minimized.

Copy link

commented Oct 11, 2018

@aethanyc Thanks for fixing that!

@rachelandrew Thanks. I'm not going to the F2F, BTW.

I still don't understand why columns (or fragmentainers in general) should establish a BFC, or what a BFC means for a fragmentainer. Fragmentainers don't capture floats, for instance, which BFCs are supposed to. I also don't understand what it solves to define them as BFCs. It would make slightly more sense if it were the column rows that establish BFCs, since they will be layout siblings of the spanners. But that would still not be quite right, since rows may be adjacent siblings (a multicol container laid out across several pages, for instance), and the float capturing gets confusing again.

But I don't think I understand the problem with spanners and margin collapsing. Spanners vs. column rows in a multicol context is very similar to regular blocks vs. lines in non-fragmented layout. Of course, block margins on inline elements don't collapse with anything (they don't even grow the line).

Spanners do not participate in the fragmentation context, like column content does.

Would it help to introduce an anonymous wrapper in the spec, similar to what we have in CSS2 when blocks are siblings of inline boxes (then we wrap the inline boxes inside an anonymous block)? I.e. wrap column content inside a wrapper, which becomes a sibling of the spanners? The wrapper could establish a BFC and a fragmentation context and do multicol layout, while the spanners are on the outside (and the actual multicol container parent will just do regular block layout, consisting of spanners and anonymous multicol wrappers). Does this make sense?

@rachelandrew

This comment has been minimized.

Copy link
Contributor

commented Oct 11, 2018

@mstensho thanks for the headsup re the f2f, if we can discuss this here then hopefully we can get this to a point where we have a proposed way forward. I'm not convinced I fully understand the issue with spanners, but it does keep coming up.

The idea of an anonymous wrapper seems to make sense to me however. It would be interesting to hear from @dbaron and @neerjapancholi on that idea.

@aethanyc

This comment has been minimized.

Copy link

commented Oct 12, 2018

@mstensho 's idea of the anonymous wrapper pretty much summarizes the ongoing implementation of column-span for Firefox. That is, the multicol container does the ordinary block layout, consisting of spanners and column-content-wrappers (which handles column balancing, etc.)

@mstensho

This comment has been minimized.

Copy link

commented Oct 17, 2018

That sounds good. Do you want me to elaborate on this proposal, or is it enough for the F2F (which I'm not attending)?

@rachelandrew

This comment has been minimized.

Copy link
Contributor

commented Oct 18, 2018

@mstensho If you think there is anything you want to clarify that would be great, in order that I can be sure your views are represented in the discussion.

@mstensho

This comment has been minimized.

Copy link

commented Oct 21, 2018

(Sorry for the late response. I wrote something on Friday, but I noticed now that I must have failed to submit it somehow)

The multi-column model

(https://drafts.csswg.org/css-multicol/#the-multi-column-model)

An element whose column-width or column-count property is not auto establishes a multi-column wrapper (needs a better name, I think). It's a regular block container, that establishes a new block formatting context. It consists of zero or more of the following types of children, in any order [*]:

  • Anonymous multi-column container: Establishes a new (multicol?) formatting context, and consists of one or more rows with columns. There may be multiple rows if there's an outer fragmentation context, such as e.g. pagination.
  • Spanners. Establishes a new formatting context (type of formatting context depends on display type; could be regular block formatting context, flex, grid, table, whatever)

[*] But there's no use-case for direct anonymous multi-column container siblings. Forbid?

Spanners inside blocks

(https://drafts.csswg.org/css-multicol/#column-span)

A spanning element may be lower than the first level of descendants as long as they are part of the same formatting context.

This is about situations like:

<div style="columns:2;">
  <div id="block" style="border:solid; background:yellow;">
    column content<br>
    column content<br>
    column content<br>
    <div id="spanner" style="column-span:all;">sorry to interrupt</div>
    more column content<br>
    more column content<br>
    more column content<br>
  </div>
</div>

Here #block contains regular column content, a spanner, and then some more regular column content. This means that #block occurs in two anonymous multi-column containers, one before and one after the spanner. This is similar to what happens in CSS 2 when we attempt to put a block-level child inside an inline - https://www.w3.org/TR/CSS22/visuren.html#anonymous-block-level :

When an inline box contains an in-flow block-level box, the inline box (and its inline ancestors within the same line box) is broken around the block-level box (and any block-level siblings that are consecutive or separated only by collapsible whitespace and/or out-of-flow elements), splitting the inline box into two boxes (even if either side is empty), one on each side of the block-level box(es). The line boxes before the break and after the break are enclosed in anonymous block boxes, and the block-level box becomes a sibling of those anonymous boxes.

In Multicolumnese, that would translate to something like:

When a block box inside a multi-column container contains a column spanner, the block box (and its ancestors within the same fragmentation context) is broken around the spanner (and any spanner siblings that are consecutive or separated only by collapsible whitespace and/or out-of-flow elements), splitting the block box into two boxes (even if either side is empty), one on each side of the column spanner. The column rows before the break and after the break are enclosed in anonymous multi-column containers, and the column spanner becomes a sibling of those anonymous containers.

Roughly: "s/inline box/block box/", "s/block-level box/column spanner/" and "s/line boxes/column rows/"

Not sure if it'd make more sense to define a simpler model if there are no spanners. There's really no need for a separate wrapper and one anonymous multi-column child then, but defining one model for all situations is simpler, spec-wise, right?

@fantasai

This comment has been minimized.

Copy link
Collaborator

commented Oct 21, 2018

@mstensho This is exactly the mental model I had during the last set of multicol discussions we had this year. 100% in favor!

@css-meeting-bot

This comment has been minimized.

Copy link
Member

commented Oct 22, 2018

The CSS Working Group just discussed Margin collapsing does not make sense with column-spans, and agreed to the following:

  • RESOLVED: margins between adjacent spanners do collapse
  • RESOLVED: margins between spanners and any other non-spanning boxes do not collapse
The full IRC log of that discussion <heycam> Topic: Margin collapsing does not make sense with column-spans
<heycam> github: https://github.com//issues/2203
<heycam> dbaron: I think there are a few different things going on
<heycam> ... I'm not sure which we've already solved
<heycam> ... one is that one thing, at the time, nothing said that the columns inside a multicol create BFCs
<heycam> ... the underlying question is can margins on column spans collapse
<heycam> ... 2 questions under that
<heycam> ... 1 is can the margin on a column span collapse with another column span right next to it
<heycam> ... that one, we could maybe argue about
<heycam> ... there are believable arguments on both sides
<heycam> ... other question is can a margin on a column span collapse the first thing in the multi col part in the col span (??)
<heycam> ... last time we looked at hte spec, it looked like it could collapse
<heycam> florian: the spec is vague enough to read it that way
<heycam> dbaron: the spec defines when margins can collapse, and nothing says they don't
<fantasai> I like Morten's proposal in https://github.com//issues/2203#issuecomment-431695940
<heycam> ... I think I would strongly like to define that the margins of column spans don't collapse with margins of things in the columns
<heycam> ... then there's the qn of can one column span's margin collapse with another
<heycam> dbaron: there's a bunch of text in the issue I haven't looked at recently
<heycam> fantasai: Morten posted a proposal, we don't have a strong definition of the multicol layout model in the spec
<heycam> ... he proposes a model for exactly how the different formatting contexts interact
<heycam> ... I think it makes a lot of sense. it gets us what dbaron said, but does that by defining the multicol container as being a BFC, and for it to contain column span and column containers, which are siblings, and they are laid out in a BFC, so the margins between spanners collapse
<heycam> ... but the spanners define their own BFCs so they don't collapse with things in the columns
<heycam> ... it's quite straightfrward and we should adopt it
<heycam> florian: I believe we've previously resolved that does say hte margins between siblings spanners collapse, and that spanners and content in columns do not
<heycam> ... at least in examples
<heycam> Rossen: we could defer this to later on after people have had a chance to read it
<heycam> florian: or I suggest we resolve on spanners collapsing with each other, but not content in the column
<heycam> ... but not on the mechanism to achieve this
<heycam> ... which we can do later
<heycam> RESOLVED: margins between adjacent spanners do collapse
<heycam> RESOLVED: margins between spanners and any other non-spanning boxes do not collapse
@FremyCompany

This comment has been minimized.

Copy link
Contributor

commented Oct 22, 2018

I just wrote a testcase, and I don't understand what browsers are doing; this is wild... @rachelandrew @fantasai @frivoal

Chrome
win10_chrome_69 0

Edge
win10_edge_insider_preview
FF
win10_firefox_62 0
Safari
macmo_safari_12 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
css-multicol-1
  
Needs Testcase (WPT)
9 participants
You can’t perform that action at this time.