Open faceless2 opened 4 years ago
There is also #4206 about text-transform
.
Note that not even Chromium legacy and Chromium LayoutNG are interoperable.
text-indent - surely no. Every browsers says no.
Actually, Chromium LayoutNG supports it, but you don't see it because of the marker alignment, so you need ::marker { direction: rtl }
. And Firefox supports it in content
markers but not in legacy markers (nsBulletFrame).
text-align - I think this has to be a no
Note Chromium LayoutNG does support it, but maybe not like you expected? If you use content: 'ab\a c'
and white-space: pre
, with text-align: left
the c
appears below the a
, and with text-align: right
it appears below the b
.
In general I would lean towards not resetting properties unless strictly necessary.
Whoops, I should have qualified that I'm testing with the versions I have here, which are the latest public ones available - your view from inside is much more accurate, thank you. I presume you have edit rights, if you want to edit that table to correct it please be my guest.
I'm making the presumption that markers will not contain newlines. As I said in #4448 I think multi-line markers are a can-of-worms - if they're allowed, the list above will certainly need updating.
so even properties that don't apply will need to be reset if they're inheritable
So... I think this is an argument for clearly defining which properties apply to raw text vs to boxes vs to line boxes or their interaction with text, and clarifying that you can set declarations on ::marker and they will inherit to the text it contains. (Applying a property to a box vs letting it inherit through and affect its contents are slightly different concepts.)
I have no problem with allowing properties that affect text and not boxes to be applied to ::marker and to inherit through, since that wouldn't change behavior as we further develop a layout model for marker boxes.
I am concerned about things like text-align
and text-indent
since they reference the edges of the line box, and therefore their behavior could change as we define the layout model for marker boxes. From my perspective, setting text-align: end !important; text-indent: 0 !important; hanging-punctuation: none !important
in the UA style sheet would be appropriate at this point in time (and at the point where layout is clearly defined, we can drop the !important
.).
For the rest, I would let text-shadow
inherit from the list item element the same as color
. I suspect it's better to block inheritance of text-transform
by default via text-transform: none
, since casing is often used to distinguish list items. Wrt resetting word-spacing
and letter-spacing
I'm unsure. We have to remember that this resetting would be applied to inside markers as well as outside ones, and for inside markers in particular might make sense to inherit the paragraph's conventions.
So I guess my proposal would be:
word-spacing
, letter-spacing
, text-shadow
, and maybe text-emphasis
(if UAs want to implement it) alongside the font properties; they all effectively just inherit through to the text rather than applying to ::marker.text-align: end !important; text-indent: 0 !important; hanging-punctuation: none !important
to the UA style sheet of any browser that supports those properties on ::marker.text-transform: none
to the UA rule for ::marker.word-spacing
or letter-spacing
resets to the UA rule for ::marker.I'm not entirely sure about the last two. @dauwhe ?
We have to remember that this resetting would be applied to inside markers as well as outside ones,
The inability to distinguish between inside and outside markers is consistently making the process of styling them (both in terms which properties apply, and what their defaults are) quite a bit more complicated. Would something like ::marker:inside
and ::marker:outside
be worth considering?
We should also consider text breaking properties. For example, it's not clear if overflow-wrap
may affect outside markers, but definitely it can affect inline ones. As usual,
overflow-wrap
when ::marker has a non-normal
content
. Otherwise the marker is unbreakable.overflow-wrap
with LayoutNG. Otherwise the marker is unbreakable.The inability to distinguish between inside and outside markers is consistently making the process of styling them (both in terms which properties apply, and what their defaults are) quite a bit more complicated. Would something like ::marker:inside and ::marker:outside be worth considering?
I suspect you're right, and that we need something like this. Whether we actually expose it is an interesting question, but given that inside markers and outside markers seem call for different behaviors, effectively that's the model we're using. Given that this doesn't introduce any selector-styling loop shenanigans, I suspect we should make it explicit and expose it.
And from there, it looks like quite a few of the resets (with or without !important
) should be on ::marker:outside
rather than on ::maker
, as the inside case seems to need much less magic.
Note that adding :inside
and :outside
, especially if they are exposed, would close the door to supporting list-style-position
in ::marker in the future, since it could introduce a circularity. https://wiki.csswg.org/faq#selectors-that-depend-on-layout
If display: marker
or position: marker
are reintroduced, these properties could be affected too.
Not really, since list-style-position
needs to be applied to the list item to take effect, not the marker. So there's no loop. Applying list-style-position
on the ::marker
would work just fine if the marker itself was a list item, and then it would change the position of ::marker::marker
.
If we don't allow having markers on markers, then it is only natural than applying list-style-position on the marker itself would do nothing.
Sure, I mean that for example Chromium legacy reads the list-style-position
of the marker itself (LayoutListMarker) instead of the list item. That's a valid interpretation because list-style-position
inherits and is not syntactically supported in ::marker. And it's not unreasonable for the ::marker to obey its own list-style-position
instead of the list item one. This interpretation won't be possible once we allow all properties in ::marker if we have :inside
and :outside
.
Exposing :inside
/:outside
could make :has()
impossible, or at least prevent it from containing pseudo-elements
:has(::marker:outside) { list-style-position: inside }
As in, that selector would result in the CSS oscillating between two states? True, but I can also think of:
:not(:has(::marker)) { display: list-item }
:has(::marker) { display: block }
I can't get :has(::marker)
to match at all, so I've not idea if this sort of loop is already covered. Preventing it is obviously important, but I don't think it's a problem specific to :inside / :outside
.
@faceless2 There is no circularity with ::marker alone, since it exists even with display: block
. See https://github.com/w3c/csswg-drafts/issues/1793#issuecomment-380762861
RESOLVED: marker exists on all elements, on ::before and on ::after but no box unless it's display: list-item
Ah, very true. I'll try to come up with another one :-)
Edit: not sure I can actually. So yes, I agree that setting list-style-position
as in your example would cause an issue, and it's probably a new one. Whether it's enough on its own to rule out :inside / :outside
is the question.
While we're considering which properties apply or don't, and reset or don't, it seems that the text-decoration properties in general, and the text-decoration-skip family of properties in particular should apply. (initially raised in #843).
Agenda+ F2F because resetting text-indent
is even encouraged in CSS Text
Since the
text-indent
property inherits, when specified on a block element, it will affect descendant inline-block elements. For this reason, it is often wise to specifytext-indent: 0
on elements that are specifieddisplay: inline-block
.
And I guess text-align: end
might be useful for multiline outside markers? Firefox is already setting that.
No strong opinion about the others, but I don't see much benefit in resetting them.
@Loirooriol My position is in https://github.com/w3c/csswg-drafts/issues/4568#issuecomment-562734422 Basically:
text-transform
as we resolved earlier.word-spacing
and letter-spacing
.The CSS Working Group just discussed [css-pseudo] Which properties to reset in ::marker
, and agreed to the following:
RESOLVED: If property applies to text and no dependency on box geometry it can be set on ::marker and inherits to text of marker
RESOLVED: Other properties which are not explicitly listed as apply to ::marker must not have an effect when set by author. UA might treat as not applying or treat them as set at UA important level but either way author should not be able to effect rendering
@Loirooriol Edits checked in, mind reviewing (and closing out the issue if it looks OK)?
What about the user origin? I would say no effect either, so that the behavior can be achieved with !important
in UA origin.
I'd like to note for the record that I strongly disagree with this resolution.
I'm fine with resetting these properties to their initial value for ::marker
in an UA rule, but they should not be !important
.
An author should be able to set them and they should have an effect.
@MatsPalmgren But this is just until the outside marker layout model becomes clear. Then it will be fine to allow authors to change the properties. IMO the resolution is a step forwards since it allows several properties that were not allowed beforehand.
This is the wrong way to go about it IMHO. Doing a long series of backward-incompatible changes to how properties work for ::marker
is very bad for authors. Also, adding UA rules to ::marker
affects both inside and outside markers.
What we should do is to: 1, define the layout model for outside markers, and 2, allow all properties on them, unless there's a very good reason to deny authors to use some of them. This is easy BTW, see #3771.
(we should) define the layout model for outside markers,
Very strongly agree with this. ::marker is implemented by Gecko, our engine, PrinceXML, PDFReactor's RealObjects, Antenna House Formatter and Weazyprint - those are the ones I'm aware of. Every one of these has had to guess at the layout rules because they're not properly defined.
I also agree with Mats that it's easy: we do largely what he describes in #3771 (specifically: remove newlines; lay out as if it were an inline-block in infinite available space so content is necessarily on a single line; align inline border box with list-item and block align as if it were on first formatted line of list-item; markers do not interact with floats and may overlap).
However as we all know, the devil is in those details (Gecko trims all trailing whitespace; we don't, Prince doesn't. Prince allows newlines; we don't, Gecko doesn't. Prince adds text-align: end
; we don't, not testable in Gecko as width can't be set). Incompatibilities are only going to get worse this longer this is left. I'd hope this issue is a sticking plaster until ::marker layout is fully defined.
@faceless2 BTW, Blink is shipping ::marker in 86 (currently beta). And WebKit shipped it long time ago, but it's a more limited version.
And about text-align
, I thought about adding text-align: end !important
to prevent inheritance (Gecko sets it to end
too, you should be able to test with li{white-space:pre}::marker{content:"a\a b c"}
). But it turns out that, in quirks mode, outside markers can occupy the whole line and are not sized with shrink-to-fit. So end
was bad in Chromium, I set text-align: start !important
instead.
About this resolution:
Other properties which are not explicitly listed as apply to ::marker must not have an effect when set by author.
I'm thinking about the visibility
property. It doesn't only apply to text, since it's able to hide box borders and things like that. But forcing visibility: visible !important
to prevent inheritance seems like an undesirable breaking change.
Or the cursor
property. It depends on the box geometry (basically it can expose the sizes of the marker). But resetting it also seems undesirable, since it has always been inherited. And the marker sizes are also exposed in getComputedStyle anyways.
So I wouldn't prevent their inheritance and it could also make sense to accept them to be set directly on ::marker.
Ok, pushed some wording changes:
Let me know if this is workable, or if the wording needs additional tweaking. CC @tabatkins for review.
As for whether this is the right approach or if we should go ahead and define marker layout... I note @MatsPalmgren’s objection and insistence that we should just define outside marker layout, but as @faceless2 noted “the devil is in those details”. I've worked on a number of layout specs, and I'm familiar with the range of issues that have been raised against outside marker layout over the years and I am quite sure this is not a trivial project. Should we do this? Yes. But in the next level, because the rest of this spec is comparatively done, and we should get it wrapped up and sent to CR.
If anyone wants to start work on the outside marker layout project right now, I invite you to start a css-lists-4 delta ED in the repository and start drafting it up. I can't prioritize it right now personally, but this isn't to say that we shouldn't be working on it. But I think it will take 1-3 years, not 1-3 months, before we shake out all the issues and that's with someone actively working on it. Which is why I don't want to hold up everything else in css-lists-3 (most of which is already shipping) to wait for it.
In the meantime, I think it's best to disable most styling of ::marker until we can work out what exactly it means, so that authors don't build a dependency on particular behaviors that we end up wanting to change as we work through all the outside marker layout issues. If you disagree on this point and would like to argue for letting whatever interop and Web-compat constraints fall out of authors exploiting various layout properties on your implementations dictate what we're able to define for outside marker layout going forward, please make a cogent argument to that effect. But I think it's safest if such properties don't have any effect until we are agreed on what exactly that effect will be.
Migrated from #4474
The specification currently states that only the following properties apply to ::marker:
...and that this list is likely to be revised. But markers don't exist in a vacuum; they're part of the tree, so even properties that don't apply will need to be reset if they're inheritable, to
initial
or some other sensible value.As of today the specification has
with
white-space
to be reset to something closely resemblingpre
(#4448).So, starting with inheritable properties in css-text and
text-shadow
from css-text-decor, and working on the presumption that markers will always be limited to a single line, we have these properties to consider:I'm going to leave
tab-size
, it's technically applicable but the only place this would ever happen is a WPT test-case. I suppose a decision has to be made, but I doubt it matters what that is.I think
hanging-punctuation
doesn't apply - all values other thanforce-end
will apply only if the text wraps, andforce-end
only applies to the end of the line. As white-space won't collapse in markers, and a space will almost always follow the punctuation I don't think that's the case, but will test for completeness (although as this depends on browser support for bothhanging-punctuation
and custom markers, it might not be a very useful test).Test is here: https://output.jsbin.com/rusilefogo
Findings:
Everyone's different, isn't that fun! To start the ball off on the discussion below, I'd suggest:
(edit: pinging @MatsPalmgren @dauwhe and @fantasai for input as suggested by @fantasai in the original issue)