New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
valtlai opened this Issue Dec 10, 2017 · 20 comments

Comments

Projects
None yet
@valtlai

valtlai commented Dec 10, 2017

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
@SelenIT

This comment has been minimized.

Collaborator

SelenIT commented Dec 11, 2017

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?

@valtlai

This comment has been minimized.

valtlai commented Dec 11, 2017

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).

@cork

This comment has been minimized.

cork commented Dec 11, 2017

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

@cpplearner

This comment has been minimized.

cpplearner commented Dec 11, 2017

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.

@SelenIT

This comment has been minimized.

Collaborator

SelenIT commented Dec 11, 2017

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")?

@upsuper

This comment has been minimized.

Member

upsuper commented Dec 11, 2017

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).

@SelenIT

This comment has been minimized.

Collaborator

SelenIT commented Dec 11, 2017

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.

@Nadya678

This comment has been minimized.

Nadya678 commented Dec 17, 2017

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.

@Nadya678

This comment has been minimized.

Nadya678 commented Dec 17, 2017

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.

@SelenIT

This comment has been minimized.

Collaborator

SelenIT commented Dec 17, 2017

@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.

@Nadya678

This comment has been minimized.

Nadya678 commented Dec 20, 2017

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.

@therealglazou

This comment has been minimized.

Contributor

therealglazou commented Jan 30, 2018

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

@SelenIT

This comment has been minimized.

Collaborator

SelenIT commented Jan 30, 2018

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.

@beckiechoi

This comment has been minimized.

beckiechoi commented Apr 11, 2018

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.

@tabatkins

This comment has been minimized.

Member

tabatkins commented Nov 2, 2018

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.

@fantasai

This comment has been minimized.

Contributor

fantasai commented Nov 8, 2018

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

@tabatkins

This comment has been minimized.

Member

tabatkins commented Nov 9, 2018

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.

@dbaron

This comment has been minimized.

Member

dbaron commented Nov 14, 2018

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.

@fantasai

This comment has been minimized.

Contributor

fantasai commented Nov 14, 2018

@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.

@css-meeting-bot

This comment has been minimized.

Member

css-meeting-bot commented Nov 14, 2018

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment