Skip to content

[selectors-4] Case-sensitive attribute selectors #2101

Closed

Description

@valtlai

The Selectors spec says:

By default case-sensitivity of attribute names and values in selectors depends on the document language. To match attribute values case-insensitively regardless of document language rules, the attribute selector may include the identifier i before the closing bracket (]).

Could there be a similar flag for case-sensitive matching?

I needed to select <ol> with type=a or type=A and apply different styles to them.

@counter-style list-a {
    system: extends lower-alpha;
    suffix: ') ';
}

@counter-style list-A {
    system: extends upper-alpha;
    suffix: ') ';
}

ol[type=a] {
    list-style: list-a;
}

ol[type=A] {
    list-style: list-A;
}
<ol type="a">
    <li>foo</li>
    <li>bar</li>
    <li>baz</li>
</ol>

<ol type="A">
    <li>foo</li>
    <li>bar</li>
    <li>baz</li>
</ol>

The desirable result is:

a) foo
b) bar
c) baz

A) foo
B) bar
C) baz

But this doesn’t work because browsers match type attributes case-insensitively, so the second style rule overwrites the first one.

Thus the actual result is:

A) foo
B) bar
C) baz

A) foo
B) bar
C) baz

Activity

  1. SelenIT commented on Dec 11, 2017

    @SelenIT
    Collaborator

    That's very strange! Both HTML specs (WHATWG and W3C) state that the value of this attribute should be compared case-sensitively (and the Rendering section of the both specs repeats this). The DOM value of the type propery of the element, which "reflects" the value of the attribute, is also reported case-sensitively. Is this wrong case attribute selector matching a bug in all browsers?

  2. valtlai commented on Dec 11, 2017

    @valtlai
    ContributorAuthor

    Yeah, that feels very strange! The type attribute is always compared case-insensitively in other elements too.

    A test case:

    <style>
        p, foo {
            display: block;
            height: 2em;
        }
    
        [type=a] { background: blue; }
        [type=A] { background: green; }
    </style>
    
    <p type="a"></p>
    <p type="A"></p>
    
    <foo type="a"></foo>
    <foo type="A"></foo>

    All the boxes are green.

    Tested with Chrome 63 (+ Canary 65), Firefox 57 (+ Nightly 59) and Safari 11 (+ Technology Preview 45).

  3. cork commented on Dec 11, 2017

    @cork

    Just wanted to clarify that this is specifically the type attribute, ANY other attribute works fine https://jsfiddle.net/vhed285n/1
    https://jsfiddle.net/vhed285n/2

  4. cpplearner commented on Dec 11, 2017

    @cpplearner

    https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors:

    Attribute selectors on an HTML element in an HTML document must treat the values of attributes with the following names as ASCII case-insensitive, with one exception as noted in the rendering section:

    • [...]
    • type (except as specified in the rendering section)
    • [...]

    The exception seems specific to user agent stylesheet.

  5. SelenIT commented on Dec 11, 2017

    @SelenIT
    Collaborator

    Well, while this probably technically explains the issue, implying that case-sensitivity of the value of this attribute is limited to the user agent stylesheet looks like a kind of self-contradiction in the spec. The note in the spec explicitly allows "to redefine the default CSS list styles used to implement this attribute in CSS user agents"; the values "A" and "a", "I" and "i" clearly have different semantics; impossibility to express this semantic in the author CSS while it is possible in the user agent CSS doesn't make much sense.

    I admit that it might be not easy to differentiate the ol element's type attribute, which probably was intended to be compared case-sensitively, from, e.g., the input element's type attribute that clearly should be compared case-insensetively, in the selectors like *[type="..."]. Maybe, since list type values don't overlap any other type values, the exception should be made for the specific values (e.g. "the type attribute value is treated as ASCII case-insensitive, except the values "a", "A", "i", and "I", which are treated as ASCII case-sensitive")?

  6. upsuper commented on Dec 11, 2017

    @upsuper
    Member

    Maybe a bit offtopic, but in Gecko, we handle type attribute of list elements manually with a mechanism called "attribute mapping", and thus we don't do any case sensitive matching for that attribute in any case. What I want to say is that, stuff in rendering section isn't required to be presented as-is in browsers as far as browsers have conformant behavior, so rendering section in specs may always be able to use some magic which CSS itself doesn't really have, although I would agree there should be as little magic as possible.

    I suppose that making type attribute in CSS matched case-insensitive has its historical reason, and making it case-insensitive in content may be the easiest approach (rather than, say, having single character case-sensitive, but case-insensitive otherwise).

  7. SelenIT commented on Dec 11, 2017

    @SelenIT
    Collaborator

    My understanding was that a general agreement has been to remove as much such browser-specific magic as possible, replacing it with CSS ways to express the same behavior, even for more complicated cases like the default behavior of the fieldset element. So I would rather try to find the CSS solution for this issue, too. If switching the case-sensitivity for the type attribute based on some heuristics would require too much complexity, I would be happy with the explicit case-sensitivity flag in addition to existing case-insensitivity flag, as @valtlai suggested above.

  8. Nadya678 commented on Dec 17, 2017

    @Nadya678

    it works properly after changing to list-b from list-A. the [] selector is case sensitive inside double quotes.

    BTW. For historical reasons selector "HtMl TABLE" is equivalent of "html table". The same manner for CSS: DISPLAY: TABLE works like display:table.

    Many developer in history write HTML/CSS code with use of only capital letters. The code is less readable but... It is fact, the sites still works.

  9. Nadya678 commented on Dec 17, 2017

    @Nadya678

    All the boxes are green.

    Tested with Chrome 63 (+ Canary 65), Firefox 57 (+ Nightly 59) and Safari 11 (+ Technology Preview 45).

    Looks like next quirks mode. Historical cause where "i" was not known for [] selector? Mainly for input[type...]?

    If we delete the manner, the old sites stop to show properly. For example HTML:

    <INPUT TYPE="SUBMIT" /> (capital letters)
    or
    <Input Type="Submit" />

    and css

    input [type="sumbit"] 
    {
       background:green;
    }
    

    Here is evidence for my words:

    https://jsfiddle.net/r7xm0dfx/

    "disabled" works (in Cr, I don't tested FF and IE) in the same manner like "type".

    The type, checked and disabled were historically often stylized but the "i" was not known in past.

  10. SelenIT commented on Dec 17, 2017

    @SelenIT
    Collaborator

    @Nadya678, you are explaining the general rule. However, the HTML spec (reference provided above by @cpplearner) contains one exception from this rule specifically made for a type attribute. And it's not clear from that spec if this exception should apply only to User Agent stylesheets or to CSS in general.

  11. Nadya678 commented on Dec 20, 2017

    @Nadya678

    After particular reading of the cited spec I think there shall be issued a bug to Chromium, Mozilla Firefox and MSIE developers.

    The case-insensitive checking of ol[type] selector blocks to style the numbered lists.

  12. therealglazou commented on Jan 30, 2018

    @therealglazou
    Contributor

    I think this is therefore not a problem in the selectors-4 spec and the current issue should be closed.

  13. SelenIT commented on Jan 30, 2018

    @SelenIT
    Collaborator

    I believe that introducing the modifier to the attribute selector that makes the comparison always case-sensitive is a valid topic for [selectors-4]. Custom styling for different types of ordered lists appears to be a valid use case for it.

  14. beckiechoi commented on Apr 11, 2018

    @beckiechoi

    Ran into the same issue as the OP. It'd be great to rely on type instead of needing to add a data attribute just to work around this issue.

  15. tabatkins commented on Nov 2, 2018

    @tabatkins
    Member

    Yup, this is a valid issue. It's sad that HTML now has case-insensitive-by-default matching of some attributes, and that set happens to include the one attribute that specifically needs case-sensitive handling on one element, but hey, them's the breaks.

    Per whatwg/html#4158 the HTML folks would like something like this, so Agenda+ for discussion.

  16. fantasai commented on Nov 8, 2018

    @fantasai
    Collaborator

    @tabatkins Umm, so why does that set include this attribute exactly? Not including it as case-insensitive seems to make the most sense?

  17. tabatkins commented on Nov 9, 2018

    @tabatkins
    Member

    Backwards-compat reasons. type values on other elements need to match selectors case-insensitively by default (because they always have, for some reason), and it's too weird to separate the attribute's behavior on ol from its behavior on other elements.

  18. dbaron commented on Nov 14, 2018

    @dbaron
    Member

    Adding an flag here that does the opposite of the i flag (probably called s for "sensitive", since the i is for "insensitive", although I suppose one could argue for c for "case-sensitive") seems reasonable to me.

  19. fantasai commented on Nov 14, 2018

    @fantasai
    Collaborator

    @tabatkins Why is it weird? It doesn't seem weird to me. Only type on OL has values which are sensitive to case, so making it the only one that's case-sensitive makes sense to me.

  20. css-meeting-bot commented on Nov 14, 2018

    @css-meeting-bot
    Member

    The CSS Working Group just discussed Case-sensitive attribute selectors, and agreed to the following:

    • RESOLVED: Add a Sensitive 's' flag
    The full IRC log of that discussion <dael> Topic: Case-sensitive attribute selectors
    <dael> github: https://github.com//issues/2101
    <dael> TabAtkins: Turns out there's a couple of HTML attributes that must be matched case insensitive in selectors.
    <dael> TabAtkins: We let UAs or Authors match case insensitive for UA stylesheet. Type attribute requires this.
    <dael> TabAtkins: ol uses type in way that requires case sensitivity
    <dael> TabAtkins: Because type elsewhere requires case insensitive it would be weird and bad if some were sensitive and some not. Just like we added i tag to allow authors to opt in, we can do opposite to force case sensitive.
    <dael> TabAtkins: Put in a UA style sheet and in a few places where author needs to match against case sensitive they use that.
    <dael> fantasai: I don't have obj to adding the flag. Confused as to why type attribute it's inherently case sensitive on ol
    <dael> dbaron: It's per attribute, not attribute+element. attribute+element is a lto more complicated and this is only use case
    <dael> TabAtkins: I like s as the flag. Insensitive = i, Sensistive=s
    <florian> +1 to "s"
    <dael> fantasai: Agreed
    <dael> astearns: Obj to adding a Sensistive 's' flag?
    <dael> RESOLVED: Add a Sensitive 's' flag
  21. verdy-p commented on Aug 29, 2021

    @verdy-p

    Is there a way to support additional flags for matching qualities/inequalities?

    Such as:

    • a 'n' flag for normalizing strings to compare (both to NFC, or equivalently NFD internally if this is more convenient to the implementation)
    • a 'k' flag (for NFKC, or NFKD): the result is also in NFC or NFD, but matching is more lenient (for example a "wide" Latin letter 'a' would match a Basic Latin letter 'a'; adding the 'n' flag to the 'k' flag would have no effect)
    • a 'f' flag for "Safe NFC" (or Safe NFD), i.e. ignoring extra "CGJ" added by the "safe normalization" to limit combining sequences to 30 characters for canonical equivalences/composition/decomposition: CGJ as splitting combining sequences into several ones ; note that the result "safely normalized" string is not necessarily "canonically equivalent", as canonical equivalence is bounded by characters with combing class 0 (including base charactrers, controls, and CGJ); using the 's' flag could be costly in terms of buffering as it may require long reordering if resulting strings are normalized by 'n' or 'k'.
    • possibly the inverse flags 'N', 'K', 'F' if one does not want to use browser's default behavior and the browser already applies some of the 3 normalizations above (all described in the Unicode Standard).

    So there could be multiple flags before the closing ']', they coulld be speciified in any order, but if they contradict each other (e.g. 'i' and 's'; or 'n' and 'N'...), the last one takes place: flags are evaluated in order from left to right.

    The idea is to support large values for attributes or pseudo-attributes containing arbitrary Unicode text (e.g. data from a large input form field or large text elements, including text fragments matched by pseudo-attributes).

    Those flags could also apply to regexp matchings using operators with '~' instead of '='.

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