Skip to content

[css-lists] canonical property order of list-style. #2624

Closed

Description

@emilio

list-style-type accepts an arbitrary identifier via <counter-style>, and thus should be last, since it can overlap with values of list-style-position.

Otherwise serializing the property and reparsing could generated different results.

Activity

  1. carlosame commented on May 9, 2018

    @carlosame

    Hi Emilio,

    list-style-type accepts an arbitrary identifier via <counter-style>, and thus should be last, since it can overlap with values of list-style-position.

    It is a bit confusing. A counter-style name is a custom identifier, and custom identifiers are defined like "if it can mess with other identifiers, it is invalid". There is the following at:

    https://www.w3.org/TR/css3-values/#identifier-value

    Note: When designing grammars with <custom-ident>, the <custom-ident> should always be "positionally unambiguous", so that it’s impossible to conflict with any keyword values in the property.

    Then, at:

    https://www.w3.org/TR/css-counter-styles-3/#at-ruledef-counter-style

    you have this:

    Note: Note that <custom-ident> also automatically excludes the CSS-wide keywords. In addition, some names, like inside, are valid as counter style names, but conflict with the existing values of properties like list-style, and so won’t be usable there.

    So inside is a valid counter-style name, but is "not usable" in the shorthand. That sounds a lot like an invalid <custom-ident>. The "Counter Styles" specification should be changed to declare inside and outside invalid counter-style names.

  2. emilio commented on May 9, 2018

    @emilio
    CollaboratorAuthor

    Hmm, the problem with that kind of thing is that it prevents you from adding keywords to list-style-position without potentially breaking code...

    Plus now you need to also make it invalid in the longhand, or then not serializing it in the shorthand.

    Seems strictly worse and more complicated than swapping the values to me...

    FF definitely allows you to write list-style-type: inside, and similar. Seems like Blink / WebKit don't implement the <counter-style-name> bits, does any other browser?

    cc @upsuper

  3. carlosame commented on May 9, 2018

    @carlosame

    Hmm, the problem with that kind of thing is that it prevents you from adding keywords to list-style-position without potentially breaking code...

    But inside and outside are there since the beginning of the shorthand, and counter-styles are a less established feature AFAIR.

    Seems strictly worse and more complicated than swapping the values to me...

    Not mutually exclusive. Your proposal make things a bit more deterministic, but still potentially confusing to users. I do not have a strong opinion in favour or against it (like if that mattered), but still think that banning those two values would be a good idea.

  4. carlosame commented on May 9, 2018

    @carlosame

    Seems like Blink / WebKit don't implement the bits, does any other browser?

    Apparently not, according to browser compatibility table at:

    https://developer.mozilla.org/en-US/docs/Web/CSS/@counter-style

    And my latest Chrome does not support the demo at:

    https://mdn.github.io/css-examples/counter-style-demo/

  5. carlosame commented on May 10, 2018

    @carlosame

    So far, I have been thinking here in terms of problems when parsing an author-specified shorthand, however when it concerns serializing:

    Otherwise serializing the property and reparsing could generated different results.

    Serialization should involve a sanity check of the individual values, that's what I do in my code (admittedly not for all shorthands) and I was assuming that browser people does the same. For example, in tests with real-world sites I found frequent cases where url() PNG images were set to background-color properties, which then bombs a blindly-produced shorthand. So my code checks for those cases.

    FF definitely allows you to write list-style-type: inside, and similar.

    That should not be a problem if you do not produce a shorthand with it (you could produce a shorthand plus the problematic property:value, or keep all the longhands in the serialization). Perhaps that should be the first thing to check out here.

  6. upsuper commented on May 11, 2018

    @upsuper
    Member

    So, we have a precedent for putting <custom-ident> at the end of shorthand to avoid conflicting with other keywords, which is animation. That case is also mentioned in the note of css-values spec as an example of designing "positionally unambiguous" grammar with <custom-ident>.

    Given that, I tend to think we should change css-counter-styles to remove that note and change the canonical order of list-style shorthand.

    cc @tabatkins

  7. faceless2 commented on May 31, 2018

    @faceless2

    (@emilio , thanks for the cross-reference, somehow I missed this issue when I opened #2724)

    The example I filed in the other issue I think is worth reproducing here for clarity

    @counter-style inside {
    ...
    }
    @counter-style outside {
    ...
    }
    ul { list-style: inside outside } /* ambiguous */
    ol { list-style: inside none } /* ambiguous */
    ol { list-style: outside } /* ambiguous */
    

    I'd be against reordering of the list-style shorthand as a solution.

    It's currently defined as <list-style-type> || <list-style-position> || <list-style-image>, which allows free reordering of the terms.

    If you want to change it to remove the ambiguity introduced by allowing list-style-type to match "inside" or "outside", you're still going to have to allow any order except when the type is called "inside" or "outside". So "list-style: decimal inside" will remain valid, but "list-style: outside inside" where the counter is called "outside" is not.

    First, the grammar is going to more complicated then necessary; something like [<list-style-style-type-except-inside-outside> || <list-style-position> || <list-style-image>] | [<list-style-position || <list-style-image>] [inside | outside]?, and that's discounting the special handling that will be required to interpret "none" correctly.

    Second, even with an unambiguous grammar it will remain confusing. An author seeing "list-style: inside outside" will have no idea what is going on without consulting the spec.

    Given so few browsers implement @counter-style at this stage, personally I feel the best solution is disallowing "inside" and "outside" as counter names. We already do it with "none" so there's precedent. Prevent authors from shooting themselves in the foot.

    The second best solution would be not allowing them to be referenced from the list-style shorthand property. As pointed out above, there is no ambiguity except in the list-style shorthand property.

  8. upsuper commented on May 31, 2018

    @upsuper
    Member

    I've mentioned before, there is precedent. The syntax of animation is

    <time> || <timing-function> || <time> || <single-animation-iteration-count> || <single-animation-direction> || <single-animation-fill-mode> || <single-animation-play-state> || [ none | <keyframes-name> ]
    

    which should allow free reordering of the terms, but <keyframes-name> is always parsed the latest, and thus something like ease ease is not ambiguous.

  9. faceless2 commented on May 31, 2018

    @faceless2

    There are plenty of property shorthands that restrict ordering: font: italic 300px bold is referencing a font called "bold", there's no ambiguity.

    But if that is going to be the solution for list-style then it has to be done without breaking the existing syntax, which allows the list-style-type as the first item in the list.

  10. upsuper commented on May 31, 2018

    @upsuper
    Member

    FWIW, Firefox has been shipping the feature using this syntax for several years, and I don't think I heard any breakage caused by this change.

  11. upsuper commented on May 31, 2018

    @upsuper
    Member

    By "this syntax", I mean <list-style-position> || <list-style-image> || <list-style-type> for the shorthand, and thus we propose to change the spec to adopt this canonical order.

  12. tabatkins commented on May 31, 2018

    @tabatkins
    Member

    font isn't a particularly relevant example; it has to have a font-family in it, and that value has to be last, so it's generally "positionally unambiguous".

    (There are exceptions to this; if the font-family is "Bold New Font", then font: italic 300px Bold New Font could potentially be parsed as a bold version of "New Font" or as a normal version of "Bold New Font". But it's usually true, unlike the animation example.)

    FWIW, Firefox has been shipping the feature using this syntax for several years, and I don't think I heard any breakage caused by this change.

    I'm extremely convinced by this argument and thus am fine with it. ^_^

  13. tabatkins commented on May 31, 2018

    @tabatkins
    Member

    @upsuper I was just doing some testing in Firefox and Chrome, and have a further question.

    none is already a valid predefined keyword for both 'list-style-type' and 'list-style-image'. Per spec, you have to treat it as being specified for whichever property doesn't otherwise have something specified. That is, in the following:

    <!DOCTYPE html>
    <ul><li id=foo>foo<li id=bar>bar</ul>
    <style>
    #foo { list-style: none decimal; }
    #bar { list-style: none url("https://www.xanthir.com/pony"); }
    </style>

    #foo should show a decimal, and #bar should show a pony.

    This conflicts with the suggested treatment of custom list-style-type, which should treat the #bar rule as invalid (as the none gets consumed by 'list-style-image', then you can't match the url() against the remaining grammar terms). So you should get decimal/disc if we're being consistent.

    Both Firefox and Chrome disagree with this, in different ways - Firefox implements the current spec, showing decimal/pony. Chrome does the opposite, showing disc/pony. (I presume it just consumes greedily, and gives list-style-type priority, rather than the opposite.) Is this behavior change okay?

  14. 71 remaining items

  15. fantasai commented on Jul 8, 2020

    @fantasai
    Collaborator

    @upsuper Added a note,

    Note: The <counter-style> values of list-style-type can also create grammatical ambiguities. As such values are ultimately <custom-ident> values, the parsing rules in [CSS-VALUES-3] apply.

  16. cdoublev commented on Sep 18, 2023

    @cdoublev
    Collaborator

    The note seems rather vague to me, whereas animation is more explicit. And serializing also requires to output an explicit outside for list-style-position when list-style-type is inside.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions