Repository navigation
[css-display] Rethinking display:contents #1313
Description
CSS Display defines display: contents as
The element itself does not generate any boxes, but its children and pseudo-elements still generate boxes as normal. For the purposes of box generation and layout, the element must be treated as if it had been replaced in the element tree by its contents
At first sight it seems intuitive, but as it is, this definition breaks some invariants that previous specs took for granted, and it's not clear what behavior is expected in some edge cases. In a short amount of time I filed #1118, #1281 and #1310, and I'm sure there are more issues.
The CSS WG also seems to think there is something wrong with display: contents:
<myles> fantasai: display: contents is a terrible idea
<myles> <general agreement>
Therefore, I wondered if these problems could be solved by defining display: contents in terms of existing mechanisms, yielding the current behavior for the common cases. This is my attempt:
❝ An element with display: contents generates a contents box, which is a special kind of inline box s.t.
-
Box-related properties have no effect on that element (but may still affect descendants via inheritance).
Note: a list with these properties may be useful, specially the ones defined with "Inherited: no (but see prose)", because without
display: contentsthey could affect descendants by other mechanisms than inheritance. -
When an contents box contains some box, the contents box is broken around that other box.
This already happens when an inline box contains an in-flow block-level box, see CSS 2.1 for details. For
display: contents, this effect would be triggered by any box.In order to "pull back" the children into the parent context, this would need to happen before anonymous fixups, blockifications, etc.
-
Various formatting contexts have rules to remove anonymous boxes that only contain whitespace. If a contents box fragment participates in such a formatting context, it is considered eligible to be removed despite not being anonymous.
This ensures that such a contents box fragment won't become a flex or grid item, won't create an empty line between blocks, won't be wrapped in an anonymous table-cell box when in a table layout, etc. ❞
It may need to be tweaked if I missed some details, but this kind of definition seems to solve the problems:
- [css-display] Should anonymous boxes always inherit through the box tree? #1118 and [css-display] Sort out interaction of "display:contents" with font-size and line-height #1249 are no longer an issue, because text directly contained in a
display: contentselement in the element tree is now contained in a contents box in the box tree. No need to introduce text boxes. - [css-display][css-flexbox][css-grid] Interaction of 'display: contents' and 'run of text' #1281 is easy, the contents box containing the text will be blockified separately from other text. If it's decided that what current implementations do is preferable, i.e. the various texts should be merged into a single flex/grid item, that could still happen by generating an anonymous inline parent box around the contents box and surrounding text (this could be induced by the contents box or by the flex/grid formatting context).
- [css-display][css-pseudo] Interaction of display:contents and ::first-line #1310 is also trivial, since a contents box is inline, the
::first-linepseudo-element will be generated outside it.
Thoughts?
Activity
frivoal commentedon May 1, 2017
The minutes don't carry the tone with which that was said, which was humor. Fantasai jokingly said "This is a terrible idea, who came up with that?" when the obvious answer was herself, and this was a lighthearted comment, in the middle of the discussion about figuring out the details. "general agreement" is probably better read as "general laughter". This has not impact on the rest of your argument, but be careful not to read much disagreement from the CSSWG about
display: contentsfrom that quote.Loirooriol commentedon May 1, 2017
Ah, thanks, I didn't know
display: contentswas an idea of fantasai XDfrivoal commentedon May 2, 2017
Well, I don't know who is the first person to bring this up, but she and tab have co-edited the spec where this has matured for a long time anyway.
fantasai commentedon May 2, 2017
Yeah, I didn't know it was me either. :p
fantasai commentedon May 2, 2017
Pretty sure I'm blaming Tab on this one: https://lists.w3.org/Archives/Public/www-style/2012Oct/0727.html
tabatkins commentedon May 2, 2017
Yeah, it was me. Seemed simple enough at the time. ^_^
SelenIT commentedon May 4, 2017
I'm not sure that introducing a new special kind of the inline box effectively for one particular case is more preferable than introducing a new generic kind of formatting object that could potentially be useful in many other text-related contexts (multidirectional text, stacking of fonts with different metrics etc., including colored fonts like OpenType-SVG, fragmentation of text decorations etc.).
Personally, I still oppose the idea of blockifying text contents of the
display:contentselement separately from their surrounding text nodes. If making these text fragments simultaneously inherit styles from the element tree and combine into one anonymous inline box with their sibling text in the box tree becomes too complicated, changing the inheritance rules might even seem the lesser evil to me. But I don't believe that it is really so complicated since browsers have already implemented the behavior that I prefer.Loirooriol commentedon May 4, 2017
To me it seemed this approach could explain various cases, but I have just noticed there is still the same problem in ::first-line (except for text directly contained). I said "since a contents box is inline, the ::first-line pseudo-element will be generated outside it", but the contents box needs to be broken by inner boxes, and then it's not clear in what point of the inheritance chain the ::first-line should be inserted.
Sorry I didn't think about this properly. I will close the issue for the time, and think if I can fix this somehow.