w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.44k stars 657 forks source link

[css-pseudo] Should ::first-line include markers? #4506

Open Loirooriol opened 4 years ago

Loirooriol commented 4 years ago

For ::first-letter https://drafts.csswg.org/css-pseudo-4/#application-in-css says

In CSS the first letter of a table-cell or inline-block cannot be the first letter of an ancestor element. [...] If an element is a list item (display: list-item), the ::first-letter applies to the first letter in the principal box after the marker.

But for ::first-line https://drafts.csswg.org/css-pseudo-4/#first-text-line only has the first part

The first line of a table-cell or inline-block cannot be the first formatted line of an ancestor element.

Should markers be excluded too? testcase

.inside {
  list-style-position: inside;
}
li::first-line {
  color: magenta;
}
li::first-letter {
  color: blue;
}
<ol>
  <li class="inside">inside</li>
  <li>outside</li>
</ol>

Chromium always excludes markers, Firefox includes them when they have inside positioning.

CC @MatsPalmgren

MatsPalmgren commented 4 years ago

There's a difference in how ::first-letter/line boxes are created though. A ::first-letter box is created "on the inside" wrapping just the text and becomes a descendant of any existing boxes on the line, whereas a ::first-line box is "on the outside" wrapping all boxes on the line. So for that reason I'm leaning towards Gecko's behavior making more sense here.

Also, if there are any display: inline list-item children there may be multiple ::marker boxes on the first line, so it would be a bit tricky to fragment the ::first-line to avoid those. I guess we could make a special rule to just skip over an inside marker of the block itself to avoid that complexity, but that seems a bit arbitrary to me and it also makes the assumption that an inside marker box is the first box on the line which may not be true if we add new pseudos in the future.

Excluding the ::marker also gives surprising results in some cases. For example, with ::first-line { font-size: 400% } I would expect an inside marker to also use that font-size. Maybe I'm just used to how Firefox handles it, but I'm not convinced Chrome's behavior is necessarily better.

Loirooriol commented 4 years ago

it would be a bit tricky to fragment the ::first-line

Note that Chromium already does so for atomic inlines: testcase.

MatsPalmgren commented 4 years ago

Interesting, but that behavior doesn't make much sense to me. It's also not compliant with the spec which is very clear that the ::first-line should wrap all children on the line. I tend to think it's just a bug in Chrome that you should fix.

bfgeek commented 4 years ago

Its not exactly clear what the spec intends, e.g. there is also this paragraph:

The first line of a table-cell or inline-block cannot be the first formatted line of an ancestor element. Thus, in <DIV><P STYLE="display: inline-block">Hello<BR>Goodbye</P> etcetera</DIV> the first formatted line of the DIV is not the line "Hello".

Which could be interpreted in different ways. E.g. skip new formatting contexts, or add logic such that "Goodbye" only matches.

There is also this paragraph:

In CSS, the ::first-line pseudo-element can only have an effect when attached to a block container. The first formatted line of an element must occur inside a block-level descendant in the same flow (i.e., a block-level descendant that is not out-of-flow due to floating or positioning).

"same flow" could be interpreted a few different ways. https://drafts.csswg.org/css-pseudo-4/#first-text-line

Loirooriol commented 4 years ago

It seems Chromium doesn't include markers when applying ::first-line's color, but ::first-line's background includes inside markers! testcase

Firefox: . Chromium:

fantasai commented 3 years ago

@bfgeek That text is describing how to find the first line. It's not saying how deep declarations applied to the first line inherit, which is a separate question. For a two-line inline-block on the first line, definitely we wouldn't pick out only the first line to style. But I think it makes sense for the ::first-line styles to inherit through.

Wrt markers specifically, I can see arguments both ways and would be interested to hear what @dauwhe / @murakamishinyu / @faceless2 think about it.

MurakamiShinyu commented 2 years ago

I tested several CSS Paged Media implementations, with the PrintCSS Playground, Test: https://printcss.live/l4zbqQ3bpr, and got the following 5 different results:

I think that the ::first-letter should always exclude markers and the ::first-line should exclude the outside marker, but for the ::first-line and the inside marker both excluding and including would make sense.

faceless2 commented 2 years ago

We match Prince, or will when we fix an issue combining first-letter and first-line.

I agree with @MurakamiShinyu, and also with @MatsPalmgren above:

if there are any display: inline list-item children there may be multiple ::marker boxes on the first line ... the ::first-line should wrap all children on the line

So while I think outside markers must be excluded, inline markers really must be considered part of the first line, for the reasons Mats raised. Here's a testcase demonstrating those reasons (which needs Firefox to display properly). If the markers weren't styled with first-line styling, it would look quite odd.

(I should add I had a good look and can't find any examples in print where first line (or first phrase) formatting is used and the paragraph begins with a numbered list. I suspect it's going to be a very unusual combination in print, at least for English. So outside of testcases for this condition I don't think it's going to come up much.)

fantasai commented 1 year ago

Agenda+ Proposed to resolve that ::first-line includes markers when list-style-position: inside and excludes them when list-style-position: outside.

(Note that for ::first-letter we already define that ::marker is excluded. This issue is only about ::first-line.)

css-meeting-bot commented 1 year ago

The CSS Working Group just discussed Should ::first-line include markers?, and agreed to the following:

The full IRC log of that discussion <emeyer> Topic: Should ::first-line include markers?
<emeyer> github: https://github.com/w3c/csswg-drafts/issues/4506
<fantasai> -> https://github.com/w3c/csswg-drafts/issues/4506#issuecomment-1367490644
<fantasai> -> https://github.com/w3c/csswg-drafts/issues/4506#issuecomment-1001846929
<emeyer> fantasai: Does ::marker part of a ::first-line or not?
<fantasai> -> https://github.com/w3c/csswg-drafts/issues/4506#issuecomment-558592436
<emeyer> …A lot of tests were done on implementations
<emeyer> …Proposed resolution is ::first-line includes markers when `list-style-position` is `inside` but excludes them when it’s `outside`
<emeyer> oriol: I think that’s fine
<TabAtkins> No strong opinion from me, but the proposed resolution seems good
<fantasai> emeyer: So this would mean that if list-style-position is outside, and color is set by ::first-line, the marker would not pick up that color
<fantasai> Rossen_: correct
<emeyer> TabAtkins: With outside positioning, it’s positioned, so we’re considering it outside the line
<Rossen_> s/ Rossen_: correct/ TabAtkins: correct/
<emeyer> fantasai: This is important if you set a background color on the first line and it wouldn’t match well with the marker, we don]t want it to apply to that outside marker
<emeyer> s/don]t/don’t/
<emeyer> RESOLVED: ::first-line applies to markers when `list-style-position` is `inside` but excludes them when it’s `outside`