[csswg-drafts] [css-display] Rethinking display:contents

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

== [css-display] Rethinking display:contents ==
CSS Display defines [`display: contents`](https://drafts.csswg.org/css-display-3/#valdef-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`](https://logs.csswg.org/irc.w3.org/css/2017-04-19/#e796824):

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

 1. 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: contents` they could affect descendants by other mechanisms than inheritance.

 2. 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](https://www.w3.org/TR/CSS21/visuren.html#anonymous-block-level) 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.
 3. 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:

 - #1118 and #1249 are no longer an issue, because text directly contained in a `display: contents` element in the element tree is now contained in a contents box in the box tree. No need to introduce text boxes.
 - #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).
 - #1310 is also trivial, since a contents box is inline, the `::first-line` pseudo-element will be generated outside it.

Thoughts?

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

Received on Sunday, 30 April 2017 21:21:30 UTC