w3c / csswg-drafts

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

[css-counter-styles-3] Should fallback use prefix/suffix of original style or fallback style? #8619

Open vitorroriz opened 1 year ago

vitorroriz commented 1 year ago

Hi everybody,

Counter styles specification says at https://www.w3.org/TR/css-counter-styles-3/#counter-styles:

Note: prefix and suffix don’t play a part in this algorithm. This is intentional; the prefix and suffix aren’t part of the string returned by the counter() or counters() functions. Instead, the prefix and suffix are added by the algorithm that constructs the value of the content property for the ::marker pseudo-element. This also implies that the prefix and suffix always come from the specified counter-style, even if the actual representation is constructed by a fallback style.

However, some related WPT tests (below) expects that the suffix and prefix come from the fallback style: imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-at-rule/suffix-fallback.html imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-at-rule/system-additive.html imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-at-rule/system-alphabetic.html imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-at-rule/system-extends.html imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-at-rule/system-symbolic.html imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-at-rule/fallback-cycle.html imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-at-rule/descriptor-prefix.html

I've created a related issue at the WPT repo (https://github.com/web-platform-tests/wpt/issues/38772) since there were related changes to the expected values here https://github.com/web-platform-tests/wpt/commit/90a953f4c4f0235160e96c8dd27d4a5e7638511d

I'd like to clarify what the proper behavior should be.

gsnedders commented 1 year ago

to quote @jfkthame in the WPT issue:

That's interesting ... and I think is a questionable feature.

See the Gecko bug https://bugzilla.mozilla.org/show_bug.cgi?id=1808995 for an example where the reporter expected (quite reasonably, IMO) that the suffix should be taken from the fallback counter-style that is actually used to generate the representation. Not doing this seems unexpected/illogical, IMO.

As an aside, I also missed the note quoted above when I first looked at this—because the first place I looked at was the definition of the fallback descriptor, which I would've expected would've (at least informatively) pointed out the fallback is partial.

tabatkins commented 1 year ago

I didn't have a particularly great reason to define it that way, except that it seemed simpler at the time. Happy to adjust things if browsers prefer to align these things.

jfkthame commented 1 year ago

I didn't have a particularly great reason to define it that way, except that it seemed simpler at the time.

To me, it seems confusing rather than simpler. If the range of a @counter-style rule excludes the value being represented, its fallback applies. fallback references another counter style. It's unnatural to expect it to reference only certain aspects of the fallback style and not the style as a whole.

Happy to adjust things if browsers prefer to align these things.

Given the lack of clear motivation for the "partial-fallback" interpretation, and that we received a specific bug report (https://bugzilla.mozilla.org/show_bug.cgi?id=1808995) relating to this (with a real-world use case), I think we should indeed adjust this.

tabatkins commented 1 year ago

I meant simpler to define - it means I can just reuse the algorithm that generates the string for counter() (which does not communicate which counter-style it eventually uses). (And this also means we're not invoking magic that's not available to authors - they'd have no way to produce a 'content' value matching what the browser does, if we made this change.)

css-meeting-bot commented 1 year ago

The CSS Working Group just discussed [css-counter-styles-3] Should fallback use prefix/suffix of original style or fallback style?, and agreed to the following:

The full IRC log of that discussion <fantasai> TabAtkins: Issue here is, per spec, when you generate counter style for a marker
<fantasai> ... it generates in your requested style, and adds prefix/suffix
<fantasai> TabAtkins: but if there's fallback to a different style (beacuse given style can't generate that number)
<fantasai> ... the algorithm doesn't pay attention to that fallback's prefix/suffix.
<fantasai> ... It uses the prefix/suffix of the chosen style
<fantasai> TabAtkins: I wrote it that way because simple, and because ability to even obtain prefix/suffix of a counter style is not accessible to author code
<fantasai> ... so if we match to the prefix/suffix that was used to finally render
<fantasai> ... authors wouldn't e able to manually reproduce that effect
<fantasai> TabAtkins: However, it seems that browser do follow the fallback and use the prefix/suffix from the finally used counter style
<fantasai> ... so have requested the spec to do that
<vitorroriz> WebKit implementation is following current spec
<fantasai> TabAtkins: If people want to change, then we can change the spec to have the prefix/suffix use the fallback style's prefix/suffix
<fantasai> vitorroriz: WebKit follows the current spec, so not all browsers follow the other way
<fantasai> vitorroriz: It came out from a bug report, but your sense about the counter API also makes sense
<fantasai> TabAtkins: we can add more API to allow authors to do the same thing, if we want to
<fantasai> TabAtkins: but it does seem that FF and Chrome do follow the fallback, and WPTs match that
<fantasai> jensimmons: This might be a good time to do what's right for authors
<fantasai> ... Safari hasn't had support for counter styles, so once we ship it could become a lot more populare
<TabAtkins> fantasai: My concern with changing the spec is you'll end up with an inconsistent prefix/suffix if you're falling back
<emeyer> fantasai: My concern with changing the spec is that you’d end up with inconsistent prefix/suffix when falling back
<TabAtkins> fantasai: Say your number system doesn' thave negatives, and you use () as your prefix/suffix
<ntim> q+
<TabAtkins> fantasai: And if falls back to decimal whihc has period as its suffix
<TabAtkins> fantasai: you'll switch styles when you fallback, functionally
<TabAtkins> fantasai: Feel like it would make more sense to keep the prefix/suffix consistent across the list
<TabAtkins> fantasai: even if your system is limited in some way
<TabAtkins> fantasai: So I think the spec behavior makes more sense form a usage pov
<TabAtkins> fantasai: I udnerstand from an impl it can be easy to just gen a string from another style
<Rossen_> ack ntim
<Rossen_> ack fantasai
<Zakim> fantasai, you wanted to ask about use cases
<fantasai> ntim: Looking at WPT, it seems that Chrome matches safari, not Firefox
<emilio> q+
<dholbert> q+
<Rossen_> ack emilio
<fantasai> emeyer: When jfkthame changed this, he had a strong opinion that it was the right thing to do
<fantasai> s/emeyer/emilio/
<fantasai> emilio: If we resolve not to change, we should check in with him
<fantasai> dholbert: Wrt fantasai's example, it was for someone using 2nd/3rd/4th, using letters as a suffix
<fantasai> ... and trying to use the appropriate suffix there
<fantasai> ... in which case it's quite reasonable to use the suffix from the fallback
<Rossen_> ack dholbert
<Rossen_> ack fantasai
<TabAtkins> right, `counter(ordinal)` would still just produce a number from that counter style
<fantasai> fantasai: It seems that that person is tryng to create a numbering system
<fantasai> ... but the prefix/suffix is only a formatting applied to counters when rendered as a list-item marker, specifically
<fantasai> ... doesn't work in other uses
<fantasai> ... seems that it should be built into the number *value* if it's part of the number, not part of the formatting prefix/suffix
<fantasai> TabAtkins: a) To build this in yourself, you'd have to do it as an additive system... which would probably work just as well?
<fantasai> TabAtkins: but aside from that, this is the reason why it makes sense to have a counter() variant that produces the full representation rather than just the number value
<fantasai> ... so that authors can reproduce what authors are doing automatically in list-item
<fantasai> TabAtkins: I would like it if authors can reproduce the functionality in API, so if we resolve to change should update API
<fantasai> TabAtkins: I don't have a strong opinion on which way to go
<TabAtkins> @counter-style ordinal { system:additive; additive-symbols: 900 "9", 800 "8", ..., 90 "9", ..., 9 "9th", ..., 1 "1st"; }
<TabAtkins> actually that's way shorter than what the bug reporter was trying to do
<fantasai> fantasai: I feel like if we want to support ordinal numbering, we should build that into the value of the counter
<fantasai> ... so I lean no change
<fantasai> ???: I tend to agree with fantasai, we should provide appropriate API
<fantasai> ... but might be a bit awkard if we don't
<Rossen_> s/???/vitor/
<fantasai> jensimmons: Building examples, there's numbering in Ethiopic which uses a suffix based in the language
<fantasai> jensimmons: It's confusing that prefix/suffix applies only to list items
<vitorroriz> I also think that we should just change it if a counter() variant api is provided to enable authors to access the fallback prefix/suffix
<fantasai> TabAtkins: that's a legacy issue, counter function has always worked this way
<fantasai> jensimmons: It does feel like prefix/suffix works with the number
<fantasai> jensimmons: feels unnatural
<fantasai> TabAtkins: I can see both ways
<fantasai> TabAtkins: whatever way we decide the default, when we create function, could make it optional
<fantasai> TabAtkins: then if what the default's doing, they can do themselves
<fantasai> jensimmons: So keep existing legacy stuff simple and add something more powerful?
<Rossen_> ack fantasai
<TabAtkins> value-prefix/value-suffix descriptors? and maybe with some more functionality to tie it to numeric value. something for counter-styles-4
<fantasai> fantasai: I think the current prefix/suffix feature is reasonable to exist
<fantasai> ... this is so that list-item counters format properly, and those prefix/suffixes should not be emitted in counter()
<TabAtkins> proposed resolution: no change from current spec, but add a counter-tbd() function that generates a string *with* prefix/suffix (exactly what fills ::marker by default) with a choice of using original or fallback prefix/suffix.
<fantasai> fantasai: but it might also be helpful to have a prefix/suffix feature that represents some segment of the number rendering itself
<fantasai> ... that's a different feature, and we have a bit of a name clash, but it's a different feature that maybe should also exist
<fantasai> ... and in that case, it's a bit more complicated, because the prefix/suffix can depend on the *value* of the counter
<TabAtkins> (oh, and put some notes in calling this behavior out)
<fantasai> ... and is an essential portion of the stringification of the number
<fantasai> TabAtkins: [reads out proposal]
<jensimmons> and I'd add that the new thing works in lists, and elsewhere counters are used.
<Rossen_> ack fantasai
<emeyer> fantasai: I’m not 100% sure about whether that’s going to make sense once we have proper support for ordinal numbering
<emeyer> …Not sure if you’d want to switch, but maybe you do
<emeyer> …If you prefix and suffix are characters, would you actually want to follow the numeric pattern
<emeyer> …I think we might want to investigate further how to do ordinal numbering
<fantasai> TabAtkins: That's a harder problem, but we still need the formatting string version of the function
<fantasai> ... so I think we should do it anyway
<Rossen_> q?
<oriol> q+
<fantasai> Rossen_: Any further thoughts or objections to the resolution?
<Rossen_> ack oriol
<fantasai> oriol: So the new function, could it be for the `content` property, or for list-style-type, or ... ?
<fantasai> TabAtkins: atm, define it as exactly equivalent to counter() and counters() but with slightly different generation for the string
<fantasai> ... so these should be usable as <string>, if the browser supports it; but would definitely be allowed in 'content'
<fantasai> oriol: so it wouldn't be for list-style-type
<fantasai> TabAtkins: no, it's not a new counter type. Just a new string-generating function
<emeyer> fantasai: Maybe an argument to the existing function?
<fantasai> Rossen_: OK, hoping this answers the question. DIdn't hear any objections
<fantasai> RESOLVED: No change to current spec. Draft ability for a counter function to return the counter string including prefix/suffix, with various fallback options
jfkthame commented 1 year ago

@tabatkins One thing I notice in the minutes is your suggestion of using an additive style to achieve what the reporter was trying to do:

<TabAtkins> @counter-style ordinal { system:additive; additive-symbols: 900 "9", 800 "8", ..., 90 "9", ..., 9 "9th", ..., 1 "1st"; }
<TabAtkins> actually that's way shorter than what the bug reporter was trying to do

However, unless I'm missing something, I don't think that actually works, does it? AFAICT this would fail for things like 900, which just generates "9" and doesn't produce any trailing zeros or the desired "th". Similarly, 901 would generate "91st", because the additive style has no reason to produce a zero in the middle.

tabatkins commented 1 year ago

Yes, you're right, and it's an issue I noticed in the past when trying to use additive to do things like this. I ended up considering it niche enough to not need addressing, since it would complicate the additive syntax significantly, and the existing real-world additive systems didn't use it (they do indeed skip digits with 0 value).

We'd probably want a more explicit generation form that was explicitly base-N and took a list of symbols to use for each digit in a given place.

Or just have another descriptor that appends to the generated representation, to address the use-case more directly.