Description
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 withdisplay: 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 adisplay: 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, breakingdisplay: 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 (fromdiv
) andbbb
would be red (fromspan
). Both would inheritletter-spacing
(fromdiv
). This would be closer to what Firefox does, but they would also receive a blue underline from::first-line
. -
Nest
::first-line
insidedisplay: 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
) andbbb
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 inheritletter-spacing
(fromdiv
). -
Let
::first-line
enclosedisplay: contents
elements that only have inline contents, but nest it insidedisplay: 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
) andbbb
would be red (fromspan
). Both would have blue underline (from::first-line
) andletter-spacing
(fromdiv
). This would be like a mix of the previous possibilities.