Join GitHub today
[css-multicol] How do elements between column-span and its multicol ancestor appear around the span #1072
The definition of
What happens to the backgrounds, padding, borders, and margins of these elements where the column span interrupts them? Do they appear as though they were a block ancestor of the column-spanning element? (What if they were inline elements?) Does relative positioning on these elements apply to the column-spanning element? Transforms? etc.
This situation is in some ways analogous to the situation that happens when an inline contains a block, which is defined reasonably thoroughly in CSS Level 2, except that this situation is a bit more general since the ancestors being split can be either inlines or blocks, whereas in the block-in-inline situation the split ancestors are only inlines.
I'd note that failing to display the background of an ancestor behind the column-spanning element could violate accessibility expectations related to colors and backgrounds.
What do existing implementations do? (IIRC, Gecko is the last engine to implement
There doesn't seem to be any trace in the spec, but I am pretty sure we discussed this at some point during the last 5 years or so. I believe we had resolved to make column span only apply to direct children of the multi-col rather than arbitrary descendants to avoid this exact problem, and due to the lack of use case presented in favor of allowing it. The creation of display:contents since then makes an even stronger case for that solution, as you can get rid of unnecessary wrapper elements.
That said, maybe not. In a document with an old fashioned structure with multiple levels of headings and paragraphs all sibling of each other, then that argument may work, but with a more structured outline and nested sections, you are fairly likely to want a multi-col on a article, nest section elements in it, and want to span a heading that is a child of a section (or of a header element. I can reasonably imagine either spanning the header element instead of the h1 it contains, or applying display:contents to it, but that does not work nearly as well on the section element.
In Blink, column content is completely interrupted by a column spanner (which is non-column content). It's similar to how blocks inside inlines behave, i.e. by interrupting them. Column content (whether it's block or inline doesn't really matter, I think?) and spanners don't interact (apart from a spanner finishing and balancing the preceding column row). No column content border/background is painted in the area occupied by the spanner. Also, the containing block width of the parent of the spanner doesn't matter. What matters is the size of the content box area established by the multicol container (measured before it's divided into columns, obviously).
For this to work sensibly, we cannot just allow any kind of ancestry between the spanner and the multicol container. The spec requires that parents do not establish new formatting contexts (I think we should disallow establishing any kind of formatting context, such as tables or flexbox - and this is what Blink does.). Then, how about relative-positioning and transforms? The most sensible thing would be to let spanners be affected by such parents, right? Or, alternatively, disallow spanners inside such ancestry. Blink ignores offsets caused by relatively positioned parents, FWIW, but I'm inclined to consider that to be a bug, seeing that this is not how blocks inside relatively positioned inlines work.
In Blink, column rows and column spanners are effectively siblings. The containing block of a spanner (and of a column row, really, but they don't have a DOM node, so kind of irrelevant perhaps) is always the multicol container.
This was referenced
Mar 8, 2017
Discussed on the call - there was some interest in simplifying to make column-span apply only to direct children of the multicol element. But there was also concern about headings nested in sections and similar use cases. It would be good to find out what browsers do and do not handle a nested heading, and have some test cases added to the test suite.
Tested this on different browsers and posting results with screenshots:
Test case: https://jsfiddle.net/5oo2gzLy/8/
So implementations seem to agree with what Morten said should happen in #1072 (comment), at least in the block case. In the inline case, only safari disagrees, and I have a hard time seeing how that's useful.
Can we agree that:
It's probably also worth testing an example with 'position: relative; left: 100px' to see if the spanning element moves left with the relative positioning of the ancestor that it breaks, similar for a 'transform', and probably also something graphical like 'filter'.
But if all implementations are acting like those elements aren't around the spanning element in those cases as well, then we should probably just stick with that approach.
Here are the screenshots for applying relative positioning, transform and filter to the parent of the column span. In most cases (except transform in chrome shown below), the column-span itself seems unaffected by these changes but apart from that there is a lot of variation so I'm posting almost all the screenshots -
1. Adding Position: relative; left: 100px;
2. Adding transform: rotate(90deg);
3. Adding filter: grayscale(100%);
Another piece that needs to be defined is the definition of emptiness for a fragment of a block or an inline that is split by a
under what conditions do you see pieces of the border/background of the div before the h2? Are the rules different for blocks and for inlines? Are the rules different for inlines split by a
It's also worth thinking about the fact that a single inline element might be split both by a block and by a
Looking at the spec, it does not seem that this behavior is invoked, even implicitly.
Do you think it would this clarification would work? changing in css-multicol's definition of
I think this would give us a sane and consistent model. Casual testing indicates this does not seem to match what existing implementations do, but then again implementations do not seem to match each other closely either, so I do not know if we need to be bound by compat here.
An added benefit of defining things this way is that it would make clear what happens to the bottom margin of a element immediately preceding the spanner and the top margin of an element immediately following, since they would be adjoining a forced break, and what happens then is defined.
We would probably need to add normative prose supporting the claim made in example 25 that when the spanning element itself is the first thing after an unforced page break, its top margin is truncated. I guess we could do that by clarifying that the forced break is on the place holder left in flow after taking the spanning element out of flow, not on the spanning element itself.
I guess something like this:
This issue was discussed in March on the call (before links were posted to github issues) so adding a link to the minutes here: https://lists.w3.org/Archives/Public/www-style/2017Mar/0037.html
Is there any additional feedback at this point?
referenced this issue
Oct 20, 2017
The Working Group just discussed
The full IRC log of that discussion<eae> Topic: column spanning issues
<eae> github issue: https://github.com//issues/1072
<eae> rachelandrew: Three issues all referring back to each other. Main issue is 1072. Propose we resolve it first and then refer back to it.
<eae> rachelandrew: Quite a long issue. dbaron raised it and florian commented quite a lot.
<eae> rachelandrew: Quick summary: When you got an element with column spanning and they're not a direct child of the multicol box container and they're still spanning. The definition says what happens to the ancestor. A good example would be a section with headings and one of them has span all.
<eae> rachelandrew: Was discussed on a call in May, June, and then went back to discuss on github and then stopp.ed
<eae> rachelandrew: Perhaps we shouldn't allow these nested things to span.
<eae> fantasai: There was some comments on allowing nesting of block but not things within another formatting context. Seems like a reasonable compromise.
<eae> fantasai: I don't think it is particularly useful for it to pop out as long as regular block elements work. The restriction makes sense from a behavior and implementation point of view.
<eae> fantasai: It is what I'd expect to happen it it makes what implementations seem to do. Makes sense to specify that behavior.
<eae> rachelandrew: I'd be happy to draft that up, makes sense to me.
<eae> fantasai: Happy to review spec text.
<eae> * discussion about florians comment in issue 1072 *
<eae> fantasai: Arbitrary depths but you cannot cross a formatting context.
<eae> fantasai: Header inside a section is a good example.
<eae> Proposed resolution: Column span applies to elements lower than the first level of decendence as long as it doesn't cross a formatting context
<eae> RESOLVED: Column span applies to elements lower than the first level of descendants as long as it's part of the same formatting context.
The Working Group just discussed
The full IRC log of that discussion<eae> Topic: Background and borders for spanners
<eae> github issue: https://github.com//issues/1072
<eae> fantasai: What if the spanner is the very first element in an element that has borders and margins and paddings?
<eae> fantasai: Is the top margin pushed to after the spanner?
<eae> fantasai: For an inline what florian suggest in the issue that would be broken, what would we do in that case?
<eae> rachelandrew: I'd like to see what implementations do at this point. Heavn
<eae> 't looked at that
<fantasai> http://software.hixie.ch/utilities/js/live-dom-viewer/?<!DOCTYPE html>%0A<span style%3D"border%3A solid%3B">%0A <span style%3D"display%3A block">splitblock<%2Fspan>%0Arest of text<%2Fspan>
<eae> fantasai: Here is an example with a block splitting an inline. You can see that the border and then the split inline.
<eae> fantasai: There is a lot of fragmentation bugs as well. Entirely separate pile of "fun". Right now we're only dealing with the multicol aspects. What are the implications for this split.
<eae> * fantasi gives an example with spanners and multicol and borders *
<eae> iank_: What appears if the spanner is the first child? What do you want to appear before the spanner? Maring border padding?
<eae> fantasai: Yes
<eae> iank_: Makes sense
<eae> fantasai: I don't know if I want that but it is what would fall out from it being analogs
<eae> Rossen: The example is having a section inside an element with border?
<eae> * fantasi draws an example *
<eae> fantasai: We have a multicol with some stuff and a section element, then we have an h2 and the h2 is a spanner.
<eae> fantasai: The section has a border
<dbaron> The in-progress Gecko implementation treats it as analogous to block-in-inline splitting.
<dbaron> although it's a little harder in a few ways, and a little different in others.
<eae> fantasai: We definitively have a border around the section. The question is where the border goes.
<eae> fantasai: Remember the header is inside the section.
<eae> fantasai: First piece of border is before the split. Then you have the block and then the border continues.
<eae> fantasai: If that is bad behavior we could say that this fragment doesn't exist and then ...
<eae> * these notes makes no sense without the visual of the example... *
<eae> Rossen: For the purpose of margin collapsing, When we take the spanner out of the element, the right element, asusming it was the only content, then margin collasoing with the red border would change.
<eae> Rossen: If the element is effectively taken out of the flow of the containing blocks flow and then I don't see a reason why this element would be breaking the position of the top border of its parent.
<nainar> Board images: https://photos.app.goo.gl/sm5cc7q8pywbSF0P2
<eae> Rossen: Now that the spanner is outside of the containing block and margin collasping would change, the red box in the digram could be pushed further down due to margin collapsing.
<eae> florian: So you're saying it would normally be posioined here but there being no margin between them there would be no space between them and the margin would not be in between. I think that is a pretty good point, arguing for leaving it up here.
<eae> rachelandrew: It is little weird, if that was one line of text up there it is still odd.
<eae> iank_: Effecitvely the spanner is treated as out of flow positioned?
<eae> Rossen: Yes, pulling it out of flow is getting tricky. We're there already
<dbaron> Reading the IRC, this doesn't make any sense to me.
<eae> iank_: That would mean that margins would collapse though it
<dbaron> but I don't know what people are pointing at.
<dbaron> I also suspect you haven't even gotten to any of the interesting issues yet... :-P
<jensimmons> hey, is what I just said getting noted?
<jensimmons> seems like a lot of this conversation is being missed, sadly
<TabAtkins> ScribeNick: TabAtkins
<eae> fantasai: I think rossens argument about the marign collapsing bebehvor this is confusing. The margin top is never going to be between the header and the first paragrapgh. If we go with the behavior where the top fragment doesn't exist then the margin is between the header and first paragraph. Then why is it above the header?
<TabAtkins> fantasai: That for me is the compelling argument to not do anything.
<TabAtkins> jensimmons: I can see a use-case where section>h2>content is the proper markup for content, and for small viewport sizes it's styled one way, and for large it's done in this diagram style
<bradk_> does box-decoration-break apply to the first fragment above the spanner?
<TabAtkins> jensimmons: I think it's fine if we let it break
<TabAtkins> rachelandrew: I think so too. Just need a resolution for that so it's tied to the spec
<TabAtkins> fantasai: I think this is a common situation, just question of where to draw top mbp; it goes above the header
<TabAtkins> rachelandrew: Happy with that.
<TabAtkins> RESOLUTION: If the fragment before the spanner is empty, nothing special happens; the top mbp is above the header, and it's just an empty fragment.
added a commit
Apr 8, 2018
I did notice while building some examples on this that where the spanner is the first child of an element with margin, padding and borders implementations then split those across the columns. In the below screenshot the second example is of this case, margin is in column box 1, then the top border, then the padding with a left and right border. This seems logical but I don't think we have any text to this regard.