While investigating ol[type="a"], ol[type="A"] et al unexpectedly matching case-insensitively in all browsers, I saw that the spec was changed a few years ago to match browser behavior despite the behavior not meeting author expectations (#225, #231).
This means that the following rules from https://html.spec.whatwg.org/multipage/rendering.html#lists are case-sensitive in UA styles but case-insensitive in author CSS:
ol[type=a], li[type=a] { list-style-type: lower-alpha; }
ol[type=A], li[type=A] { list-style-type: upper-alpha; }
ol[type=i], li[type=i] { list-style-type: lower-roman; }
ol[type=I], li[type=I] { list-style-type: upper-roman; }
This prevents authors from applying custom uppercase and lowercase counter styles. The following does not work correctly on any version of Firefox that supports counter styles (no other browser supports counter styles at the moment):
https://jsfiddle.net/BoltClock/kn90jcev
@counter-style custom-lower-alpha {
system: extends lower-alpha;
suffix: ') ';
}
@counter-style custom-upper-alpha {
system: extends upper-alpha;
suffix: ') ';
}
/*
* These rules match both <ol type="a"> and <ol type="A">,
* causing the uppercase rule to apply to both list types.
*/
ol[type="a"].custom-counter-style {
list-style-type: custom-lower-alpha;
}
ol[type="A"].custom-counter-style {
list-style-type: custom-upper-alpha;
}
This also prevents authors from resetting list styles to presentational defaults, though that use case is better served by list-style: revert anyway.
The attribute selector matching itself remains case-insensitive in author CSS in all browsers. I plan to file a bug against every browser for this, but in the meantime I think the change to the spec should be reverted so it requires case-sensitive matching everywhere.
Given that the type attribute likely has to continue to match case-insensitively elsewhere, it seems somewhat suboptimal to make it depend on the element type. I strongly suspect the reason browsers didn't have this to begin with is because they don't want the additional branching.
I suspect we want something else. Either something like ol[type=a c] (as opposed to the i modifier) or perhaps a global switch to disable case-insensitive attribute value matching. Depends a bit on how that's implemented.
cc @tabatkins @fantasai
Some additional thoughts:
Is the type attribute of ol considered presentational by nature, or does it just happen to have presentational hints? Maybe it was only intended to be used in UA stylesheets and not for authors. Then again, the spec itself does describe a semantic use case for the attribute, and it's not marked as "Obsolete. Use CSS instead." so it might still be a valid use case to apply styles based on this attribute.
I just found out that it's possible to override the predefined lower-alpha and upper-alpha counter styles directly, which completely avoids this problem for those who simply want to override the predefined styles for all matching ol elements without applying it to specific ones:
@counter-style lower-alpha {
system: alphabetic;
symbols: a b c d e f g h i j k l m n o p q r s t u v w x y z;
suffix: ') ';
}
@counter-style upper-alpha {
system: alphabetic;
symbols: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z;
suffix: ') ';
}
Bit of a pain to have to spell out the symbols, but it works. I still can't apply my own counter styles, though.
It's not considered presentational, but it does have an effect on the default presentation. It's totally valid to apply styles based on it too, but it's unclear that alone is sufficient rationale to change selector matching in complicated ways (I don't think it is).
An explicit "make this case-sensitive" hint, for the handful of cases where something is by-default case-insensitive, would be good. Right now it's actually just straight-up impossible to represent the default ol styling with CSS rules. :(
Most helpful comment
It's not considered presentational, but it does have an effect on the default presentation. It's totally valid to apply styles based on it too, but it's unclear that alone is sufficient rationale to change selector matching in complicated ways (I don't think it is).