This:
html input[disabled] {
cursor: default;
}
means I have to get more specific to override it.
I'm sure there's good reason to have the html in there, but I'd love to understand why – and maybe a comment could be added to explain it? Happy to contribute that comment once I understand the reason.
Ah… I guess it is to win over html input[type="button"] in
/**
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
* and `video` controls.
* 2. Correct inability to style clickable `input` types in iOS.
* 3. Improve usability and consistency of cursor style between image-type
* `input` and others.
*/
button,
html input[type="button"], /* 1 */
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button; /* 2 */
cursor: pointer; /* 3 */
}
If so, how about splitting out cursor: pointer; /* 3 */ into a separate selector group, so there's less unnecessary escalation of specificity? Specifically, wouldn't this work:
/**
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
* and `video` controls.
* 2. Correct inability to style clickable `input` types in iOS.
*/
button,
html input[type="button"], /* 1 */
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button; /* 2 */
}
/**
* Improve usability and consistency of cursor style between image-type `input` and others.
*/
button,
input[type="button"],
input[type="reset"],
input[type="submit"] {
cursor: pointer;
}
/**
* Re-set default cursor for disabled elements.
*/
button[disabled],
input[disabled] {
cursor: default;
}
This might actually be a good use-case for lowering the selector weight of inputs with attribute selectors. Thoughts, @battaglr?
We’re unsure how to test the possible performance impact of reducing the selector weight on these elements, as selectors match RTL, but at the level of compound selector, not simple selector, which is why qualifying by tagname is good. We have been asking folks on Twitter and Tab Atkins even put out a request on our behalf.
If we don’t have any data, it’s unsafe to remove these. I would like to, but how do we validate if there is any impact?
I think that what @henrik is suggesting is a nice and smart idea, since we are not creating less performant selectors, but splitting the rules.
cursor property, which is a good default, but I unterstand some people may want to change it —mostly the disabled state, in which the value not-allowed is not that uncommon.Agreed. I am using @benfrain’s excellent CSS performance revisited post to evaluate the performance of a qualified selector with an attribute and value input[type="search"] against an unqualified selector with an attribute and value [type="search"].
I modified @benfrain’s CSS Selector Test to test the performance difference between using a qualified selector input[type="search"] and using an unqualified selector [type="search"]. The tests for each were identical; a DOM of 1000 identical chunks of markup.
I ran each of the tests 16 times, manually checking that the results were somewhat consistent, and then only keeping the last 6. Each result contained the number of milliseconds it took to make the selection; the lower the number being the faster the selection.
I calculated the difference between the unqualified selector tests and qualified selector tests. When the difference was a positive number then it meant the qualified selector is faster, and when the difference was a negative number then it meant the unqualified selector is faster. I expected the difference to be fairly minimal, with the qualified selector being slightly faster.
As it turns out, removing the qualifier actually improved performance more often than not.
Here are the results:
| Chrome 49 | Test 1 | Test 2 | Test 3 | Test 4 | Test 5 | Test 6 |
| --- | --: | --: | --: | --: | --: | --: |
| [type="search"] | 276 | 290 | 282 | 283 | 287 | 319 |
| input[type="search"] | 282 | 293 | 301 | 318 | 296 | 305 |
| _difference_ | -6 | -3 | -19 | -35 | -9 | 14 |
| Firefox 45 | Test 1 | Test 2 | Test 3 | Test 4 | Test 5 | Test 6 |
| --- | --: | --: | --: | --: | --: | --: |
| [type="search"] | 203 | 197 | 205 | 194 | 234 | 186 |
| input[type="search"] | 209 | 213 | 208 | 219 | 196 | 186 |
| _difference_ | -6 | -16 | -3 | -25 | 38 | 0 |
| Safari 9.1 | Test 1 | Test 2 | Test 3 | Test 4 | Test 5 | Test 6 |
| --- | --: | --: | --: | --: | --: | --: |
| [type="search"] | 90 | 88 | 88 | 90 | 89 | 85 |
| input[type="search"] | 89 | 87 | 86 | 91 | 87 | 87 |
| _difference_ | 1 | 1 | 2 | -1 | 2 | -2 |
| Edge 13 | Test 1 | Test 2 | Test 3 | Test 4 | Test 5 | Test 6 |
| --- | --: | --: | --: | --: | --: | --: |
| [type="search"] | 2671 | 2853 | 2871 | 2822 | 2272 | 2702 |
| input[type="search"] | 2861 | 2597 | 2391 | 2501 | 2741 | 2357 |
| _difference_ | -190 | 256 | 480 | 321 | -470 | 345 |
| Android 5 | Test 1 | Test 2 | Test 3 | Test 4 | Test 5 | Test 6 |
| --- | --: | --: | --: | --: | --: | --: |
| [type="search"] | 923 | 909 | 912 | 922 | 903 | 894 |
| input[type="search"] | 1062 | 1029 | 900 | 944 | 1155 | 966 |
| _difference_ | -139 | -120 | 12 | -22 | -252 | -72 |
| iOS 9 | Test 1 | Test 2 | Test 3 | Test 4 | Test 5 | Test 6 |
| --- | --: | --: | --: | --: | --: | --: |
| [type="search"] | 94 | 69 | 100 | 173 | 83 | 68 |
| input[type="search"] | 74 | 98 | 101 | 86 | 77 | 197 |
| _difference_ | 20 | -29 | -1 | 87 | 6 | -129 |
The results delightfully suggest that [type="search"] is more performant, albeit minimally. I would agree with what Ben wrote:
it is absolute folly to worry about the type of selector used ... the difference between fastest and slowest selectors isn’t massive, even on a ludicrous DOM size
The significance of these tests is that we should be able to safely reduce the selector weight of input types without negatively impacting the performance of large pages using normalize.css.
A PR is in to update selector weights and resolve this side-affect.
Most helpful comment
A PR is in to update selector weights and resolve this side-affect.