Repository navigation
[css-lists] How should spaces be treated in markers? #4448
Copy link
Copy link
Closed
Labels
Closed Accepted by CSSWG ResolutionChanges backed by a CSSWG resolution.Changes backed by a CSSWG resolution.Commenter SatisfiedCommenter has indicated satisfaction with the resolution / edits.Commenter has indicated satisfaction with the resolution / edits.css-lists-3Current WorkCurrent Work
Description
The white-space property doesn't apply to markers, but how do spaces behave in markers?
Consider
<ol>
<li class="marker default inside space-1">-</li>
<li class="marker default inside space-2">-</li>
<li class="marker default inside space-n">-</li>
<li class="marker default outside space-1">-</li>
<li class="marker default outside space-2">-</li>
<li class="marker default outside space-n">-</li>
<li class="marker pre inside space-1">-</li>
<li class="marker pre inside space-2">-</li>
<li class="marker pre inside space-n">-</li>
<li class="marker pre outside space-1">-</li>
<li class="marker pre outside space-2">-</li>
<li class="marker pre outside space-n">-</li>
<li class="type default inside space-1">-</li>
<li class="type default inside space-2">-</li>
<li class="type default inside space-n">-</li>
<li class="type default outside space-1">-</li>
<li class="type default outside space-2">-</li>
<li class="type default outside space-n">-</li>
<li class="type pre inside space-1">-</li>
<li class="type pre inside space-2">-</li>
<li class="type pre inside space-n">-</li>
<li class="type pre outside space-1">-</li>
<li class="type pre outside space-2">-</li>
<li class="type pre outside space-n">-</li>
</ol>ol { font-family: monospace}
.pre { white-space: pre }
.inside { list-style-position: inside }
.marker.space-1::marker { content: 'a b' }
.marker.space-2::marker { content: 'a b' }
.marker.space-n::marker { content: 'a\a b' }
.type.space-1 { list-style-type: 'a b' }
.type.space-2 { list-style-type: 'a b' }
.type.space-n { list-style-type: 'a\a b' }The results in Firefox, Chromium legacy and Chromium with LayoutNG and look like
| Firefox | Chrome leg| Chrome NG |
| ------- | --------- | --------- | --------- |
| marker | a b- | 1. - | 1. - |
| default | a b- | 2. - | 2. - |
| inside | a b- | 3. - | 3. - |
| ------- | --------- | --------- | --------- |
| marker | a b- | 4. - | 4. - |
| default | a b- | 5. - | 5. - |
| outside | a b- | 6. - | 6. - |
| ------- | --------- | --------- | --------- |
| marker | a b- | 7. - | 7. - |
| pre | a b- | 8. - | 8. - |
| inside | a | 9. - | 9. - |
| | b- | | |
| ------- | --------- | --------- | --------- |
| marker | a b- | 10. - | 10. - |
| pre | a b- | 11. - | 11. - |
| outside | a | 12. - | 12. - |
| | b- | | |
| ------- | --------- | --------- | --------- |
| type | a b- | a b- | a b- |
| default | a b- | a b- | a b- |
| inside | ab- | a b- | a b- |
| ------- | --------- | --------- | --------- |
| type | a b- | a b- | a b- |
| default | a b- | a b- | a b- |
| outside | ab- | a b- | a |
| | | | b- |
| ------- | --------- | --------- | --------- |
| type | a b- | a b- | a b- |
| pre | a b- | a b- | a b- |
| inside | ab- | a b- | a |
| | | | b- |
| ------- | --------- | --------- | --------- |
| type | a b- | a b- | a b- |
| pre | a b- | a b- | a b- |
| outside | ab- | a b- | a |
| | | | b- |
That is:
- In Firefox,
- ::marker's
contentobeys thewhite-spaceproperty inherited from the list-item. list-style-typeignoreswhite-space, and- spaces are preserved
- newlines are removed (really removed, not just collapsed)
- Presumably
list-style-typewill obeywhite-spaceafter https://bugzil.la/1542807
- ::marker's
- In Chromium with legacy layout,
- ::marker is not supported
list-style-typeignoreswhite-space, and- spaces are preserved
- newlines are collapsed into spaces.
- In Chromium with LayoutNG,
- ::marker is not supported
- For inside positioning,
list-style-typeobeys thewhite-spaceproperty inherited from the list-item - For outside positioning,
list-style-typeuseswhite-space: pre
What's the expected behavior?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Closed Accepted by CSSWG ResolutionChanges backed by a CSSWG resolution.Changes backed by a CSSWG resolution.Commenter SatisfiedCommenter has indicated satisfaction with the resolution / edits.Commenter has indicated satisfaction with the resolution / edits.css-lists-3Current WorkCurrent Work
Activity
faceless2 commentedon Oct 24, 2019
Three observations on this:
If spaces are in ::marker, they're there because the stylesheet explicitly listed them, either in the
contentproperty or in@counter-style. Trailing spaces (one or more) are also used to separate the marker from the content. So whitespace should definitely not be collapsed, at least not by default, which means inheriting white-space from the parent is not an option. At the very least you'd need a user-agent rule like::marker { white-space: N }, or functional equivalent.Markers are aligned against the first in-flow linebox descendent of the list-item - so if the list-item's first child is a block, for example, it's that child's linebox. I can't find my notes on this right now but I am pretty certain they also contribute to the height of that linebox - i.e. the initial list-item linebox is as at least as high as the marker. For this reason I think allowing newlines might prove problematic; you're then effectively trying to size a linebox to accomodate content which is already multiline. Until I can recall the tests that will back me up on this point, I'm prepared to be corrected on this one.
inside positioning just generates a regular inline, so poses no more problem for white-space than any other inline. Inside markers should probably be considered separately to outside markers.
So if removing newlines does prove critical, you can't allow the user to override white-space on the ::marker, in case they try to keep newlines.
(edit: this is on the presumption that
list-style-typeis, or will be, implemented as a::marker)MatsPalmgren commentedon Nov 9, 2019
The styling restrictions on
::markershould be removed IMO. There's no reason whatsoever that::markercan't support the same properties as::before/::afterdoes. (with some minor restrictions ondisplay/positionvalues for outside markers perhaps)MatsPalmgren commentedon Nov 9, 2019
Replying to @faceless2 points above:
True, but it's also trivial for authors to use a non-collapsing space if that's what they want:
\A0.Currently, outside markers are aligned outside the inline/block start/start edge but I think we should enable authors to align the marker elsewhere in the future, for example
::marker { align-self:center/end }to align it in the block-axis. I think it would be a mistake for the spec to assume that these lineboxes are always going to be edge-to-edge like they currently are.That doesn't preclude supporting multi-line markers though. We could use the first linebox in the marker to implement that legacy behavior.
Agreed, an inside marker should just be a normal inline box by default. I'm strongly in favor of allowing authors to style it with
displayetc though, to achieve whatever layout they want.MatsPalmgren commentedon Nov 9, 2019
I tend to think that trailing spaces should collapse. That's consistent with how this behaves:
As I suggested in #3771, we should consider an outside
::markerbox as having a blockifieddisplayvalue. The collapsing behavior falls out from that without adding any special rules.Loirooriol commentedon Nov 9, 2019
I'm not that sure about non-inherited properties. But I tend to agree for inherited properties (except
list-style-*I guess). The restriction can be bypassed anyways by setting the desired marker value to the list-item, let the marker inherit it, wrap the list-item contents inside some container, and reset the value in that container. But this sucks for authors.The point is that
@counter-styleis being used on the wild, with the expectation that spaces won't collapse. Changing the behavior to no longer collapse by default would break existing code.Also, IMO using U+00A0 is semantically wrong, non-breaking spaces are supposed to be used to avoid breaks between specific pairs of words, not to avoid whitespace collapsing (I know it's a lost battle, but still). The proper way to control whitespace collapsing is the
white-spaceproperty.So I tend to think
We should settle on some default value for
white-spacein markers (pre?) and assign it in UA origin.This default value may depend on whether the marker is inside or outside, e.g.
where
:inside-markerand:outside-markerwould be internal pseudo-classes that can only be used in UA origin (not exposed to the web).But probably it's simpler to always have the same default value.
Decide what to do with multiline markers.
At some point, let authors customize marker's
white-space(among other properties) with their desired value.faceless2 commentedon Nov 10, 2019
Markers are separated from the body of the list with white-space. If you collapse that away by default, a space character in
counter-suffixbecomes useless. At the very least you're going to have to redefined the default value ofcounter-suffixto '\00A0', and if users are setting their owncounter-suffixthen things will probably break.(Incidentally, although Safari currently doesn't support
@counter-styleyet, bullets are separated from the body with two spaces.)Re. the marker alignment, you've already got https://drafts.csswg.org/css-lists-3/#marker-side which allows a little control. @MatsPalmgren, does this cover the case you had in mind?
My main concern with block-axis marker positions, multi-line markers etc is that the css-lists modules seems to have had considerably less love than it deserves. List bullets were first described in HTML 1, and from what I can see browsers haven't changed much in the way they position them since then.
@counter-stylecounter-style: discwith some sort of custom circle rather than the U+2022 bullet character suggested (although not required) incss-counters-3. Effectively, this meansfont-familyisn't useful withcounter-style: disc. Same for circle and square.inline-blockMy point is there seems to be relatively little appetite (for both the specification and implementations) to move forward. For that to change, I'd be inclined to severely limit the scope of what markers can do - at least for
css-lists-1.Loirooriol commentedon Nov 10, 2019
Actually it's a bit more complicated, and depends on
list-styleproperties. But in most cases WebKit uses a separation of 1 space plus 1/3 of the font ascent.You can force the U+2022 character with
list-style-type: "\2022 ". Firefox has supported it for a long time since version 39, and recently I have implemented it for Chromium 79 and WebKit.Well, WebKit shipped a limited version of ::marker 2 years ago, more recently Firefox shipped it completely, in Chromium I have implemented the WebKit behavior behind a flag and I'm working on completing it. This allows marker customizations, and will be much more powerful when we start accepting more properties in it. So things are moving forward, though it's true that outside positioning is heavily underspecified.
MatsPalmgren commentedon Nov 10, 2019
That seems reasonable to me, on the condition that the property works normally so that authors can override it as they see fit.
Using the same value for both seems better to me.
Fwiw, when I experimentally added
::marker { white-space:pre }in Gecko the test fallout was the expected.MatsPalmgren commentedon Nov 10, 2019
I was thinking of hypothetical marker positions where the marker's inline-axis end edge (and its trailing space) isn't adjacent to the principal box. (I'm not sure if that's possible with
marker-side.)Anyway, if we allow authors to override the default white-space behavior then that's not really a problem.
faceless2 commentedon Nov 10, 2019
On re-reading my post I should clarify my observation on the relative lack of momentum on css-lists isn't a dig. The fact list bullets are largely as they were 20 years ago clearly means that end-users are not shouting about them the way they are over... well, over everything else I suppose. We've recently got it working, so from the perspective of a clean-room implementation the spec is noticeably thinner than much of the rest of CSS - that's the basis for my comment, no more.
I'm fully aware of the effort required to specify this completely and now our W3C membership is complete, hope to pitch in on this over the next few months.
MatsPalmgren commentedon Nov 11, 2019
Here's my proposal for this issue:
white-spaceas a property that applies to::marker::marker { white-space:pre }to the UA sheet::markerbox has itsdisplayvalue blockified. (This makes it clear that if an author overrides white-space with saywhite-space:normalthen any trailing space in an outside marker's text is expected to be truncated as it normally would at the line end in a block.)I think those changes would define how white-space should be handled unambiguously.
I think we can punt on the other issues for now (multiline marker, allowing more properties etc).
12 remaining items
[css-pseudo] Use 'white-space: pre' by default in ::marker
faceless2 commentedon Jan 9, 2020
Adding
text-space-collapse: preserve-spacesas well aswhite-space: prewould prevent long lines from wrapping, and disallow explicit newlines. https://www.w3.org/TR/css-text-4/#white-space-collapsing.[css-lists-3] Require outside markers to be block containers, but don…
[css-lists-3] Require white-space: pre on markers. Allow UA to collap…
fantasai commentedon Jul 8, 2020
@Loirooriol Mind reviewing? :) (Feel free to close and mark Commenter Satisfied if it looks good to you.)
Loirooriol commentedon Jul 8, 2020
@fantasai The change looks good, according to the resolution. But it's problematic for inside markers, #4891. So maybe there should be a note about the problem, or add
text-space-trim: discard-afterin the UA styles or something?[css-lists-3] Add more comments to issue. #4448 (comment)
fantasai commentedon Jul 8, 2020
@Loirooriol Done, thanks!
Loirooriol commentedon Jul 9, 2020
Thanks, looks great!