Skip to content

[css-display][css-pseudo] Interaction of display:contents and ::first-line #1310

Open
@Loirooriol

Description

@Loirooriol

Typically, inheritance follows the element tree. However, the ::first-line is able to "hijack" the inheritance of some properties:

During CSS inheritance, the portion of a child element that occurs on the first line only inherits properties applicable to the ::first-line pseudo-element from the ::first-line pseudo-element.

The problem is that the place in which ::first-line is generated depends on the box tree, and display: contents generates no boxes, so I'm not sure how they interact.

The implementations of display: contents (Firefox and Chrome) are not interoperable, and both seem undesirable:

  • On Firefox, inline contents in the first line are not affected by ::first-line if they are inside an element with display: contents. They inherit directly from that element instead. Example. Bug 1305951
  • On Chrome, the mere existence of ::first-line prevents inline contents in the first line from inheriting from a display: contents parent. They inherit first from ::first-line, and then from the nearest non-display: contents ancestor. Example. Bug 706316

For example, https://jsfiddle.net/0q8paowL/

main::first-line { color: blue; text-decoration: underline; }
div { display: contents; color: green; letter-spacing: 10px; }
span { display: contents; color: red; }
<main>
  <div>aaa <span>bbb</span> <p>ccc</p></div>
</main>

I will attempt to represent the inheritance using a fictional tag sequence, which I'm not sure is right because ::first-line only exists in the box tree and display: contents in the element tree.

I see three reasonable possibilities:

  • Place the ::first-line as outermost as possible, breaking display: contents elements if necessary:

    <main>
      <main::first-line>
        <div no-box>aaa <span no-box>bbb</span></div>
      </main::first-line>
      <div><p>ccc</p></div>
    </main>

    Then aaa would be green (from div) and bbb would be red (from span). Both would inherit letter-spacing (from div). This would be closer to what Firefox does, but they would also receive a blue underline from ::first-line.

  • Nest ::first-line inside display: contents elements, breaking it if necessary:

    <main>
      <div no-box>
        <main::first-line>aaa</main::first-line>
        <span no-box><main::first-line>bbb</main::first-line></span>
        <p>ccc</p>
      </div>
    </main>

    Then aaa would be blue (from ::first-line) and bbb would be blue (from ::first-line). Both would have blue underline (from ::first-line). This would be closer to what Chrome does, but they would also inherit letter-spacing (from div).

  • Let ::first-line enclose display: contents elements that only have inline contents, but nest it inside display: contents elements that have some block-level.

    <main>
      <div no-box>
        <main::first-line>aaa <span no-box>bbb</span></main::first-line>
        <p>ccc</p>
      </div>
    </main>

    Then aaa would be blue (from ::first-line) and bbb would be red (from span). Both would have blue underline (from ::first-line) and letter-spacing (from div). This would be like a mix of the previous possibilities.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions