How long can a CSS selector be?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



How long can a CSS selector be?



How long can a CSS selector be?



I'm not too interested in what the 'spec' says, but rather, what browsers can actually handle. So far, I'm only aware of one browser which chokes on (very) long selectors; chrome.



Edit: Example where Chrome does not apply CSS rule to some countries, e.g. the US, Turkey, Syria and the UK, and the CSS. There are 7 selectors, and at least #5 is too long for some browsers.





Here you go- jsfiddle.net/WdyBE
– nice ass
Dec 29 '13 at 19:20






"I'm not so interested in what specs say" That's OK, because the specs don't say anything about it.
– BoltClock
Dec 30 '13 at 6:12






@ScottS: Thanks, but are you sure your results are not correlated with available memory? Because I get to see around 2048 red divs. It could be that Chrome allocates a smaller percentage of the free memory than other browsers
– nice ass
Dec 31 '13 at 13:06





@onetrickpony: 2048 matches what I got for the third fiddle link ("it begins to fail at 2049") in my paragraph about removing > * from the string (not sure what you were looking at to test). So if it does have something to do with memory (which I am not sure about), then we may match memory.
– ScottS
Dec 31 '13 at 13:57



> *




3 Answers
3



ScottS concluded Chrome handles 1366 selectors. Why 1366?



1366 * 3 = 4098



Why 3? There are 3 components in this selector: .y1366 .c1 > *.
4098 is the limit of total number of selector parts. Proof here (I added > * to the first selector only and it marked 4095 elements instead of 4096).


.y1366 .c1 > *


> *



A group of 4096 selectors will have the remaining ones completely ignored. Example:


.z .y1, .z .y2, .z .y3,..., .z .y3background-color:red



In the example each selector has 2 components:


.y1 > *
Component 1: .y1
Component 2: *



Every selector placed after the 2048th is ignored. Why 2048? Because each selector has 2 components and the limit is 4096. Not convinced?



In the example above each selector has one component:


.y1, .y2, .y3 ...



Only the first 4096 selectors are working. Chrome doesn't have a limit, so all of the selectors should work. Yet after a certain point, remaining selectors are completely ignored. This bug existed for at least 2 years. IE9 and below have a limit of 4095 selectors.



A large group of selectors, one of them having two components .bdy .y1 will, after 4096 combined components cause the element with class bdy to be affected.


.bdy .y1


bdy


.bdy .y1, .y2, .y3, ... .y4097background-color:red



The CSS selector group above causes an element by class name bdy to have background-color:red applied. The condition is to have 4096 selectors after one selector with two components.


bdy


background-color:red



In the example above the body is applied with red color due to a 4096 selector (after one which targets a child of an element with class name bdy which has class name y1). The bug will cause the parent to be affected.


bdy


y1



In .bdy .y1 the element .y1 (under parent .bdy) is targeted, yet an element bdy is also affected. If you move the two component selectors 10 places forward you can create 10 more selectors until this bug manifests. That implies the bug occurs when total number of component selectors reaches 4096.


.bdy .y1


.y1


.bdy


bdy



They are not going to fix it. This problem will happen only if all selectors are on one line. So just do:


.c1 .y1,
.c1 .y2,
.c1 .y3...



instead of:


.c1 .y1, .c1 .y2, .c1 .y3...





My edit introduced an error (> * changed to >) but review-click bots deny its correction. Feel free to edit (or override the rejection).
– user4157124
Nov 2 '17 at 17:59


> *


>





Seems like, In chrome 63, group of 4096 selectors is no longer a bar
– Rajkishore
Dec 28 '17 at 10:37



If I remove all the selector sets up through .y2010 .au > * (the first 97), then the .y1990 .us > * set first shows up. That seems to imply a limit is the issue. If I calculated it correctly, the limit for your code appears to be 1366 for Chrome (these numbers came from importing it into an excel spreadsheet with comma delimitation, then doing a count on the cells). So splitting it into 2 or 3 smaller groups may resolve the issue.


.y2010 .au > *


.y1990 .us > *



One thing that I cannot quite explain is in the Chrome developer tools, if I hide the .land fill: lightgray then the correct color for the .us and others shows up, which almost seems to indicate it is "hiding" or "overriding" the color somehow, which does not quite make sense. I cannot figure out where it is getting the correct color from when the .land is hidden.


.land fill: lightgray


.us


.land



First Round - Not Simply a Set Number of Selectors



However, it had seemed that it may be more total characters rather than total number of selectors, as Chrome handles these 1366 selectors fine (thanks to onetrickpony's initial fiddle that helped me come up with this testing example), and even one more to 1367 is okay.



But with the html and css set up to match a little closer to your real use case and it works at 1366 items, but I get an odd leakage of the red color to the body itself in Chrome if it is 1367 items. (Perhaps this is related to what I experienced with the .land color oddity noted above for your real use case.)


body


.land



If I remove the > * portion of the css then 1367 items again works, so it is not the * selector itself that is the issue, because if that is changed to div it fails again. However, the * selector may account for the odd color leakage, because in this example with the removed > * on my Chrome it begins to fail at 2049 as I would expect it to fail (i.e. losing color in the divs, rather than having color leakage like the previous failures). Note that this example of 50,000 elements (WARNING: you may get a "stop script" warning if you load it, just by-pass a time or two and it should complete the load) still works in Firefox and IE10 for me. This is true even if I add back the > * in both browsers, whereas in Chrome it reverts to doing the background leakage again (which further seems to confirm the * selector may have something to do with the odd color behavior).


> *


*


div


*


> *


2049


> *


*



Second Round - Some Combination of # of Selectors and # of Characters



From one of the failure examples above, I had calculated that the total number of characters would have been roughly 20500 for failure. Yet I can get 50002 characters without an issue here, and 100002 here -- so it must be some combination of X number of selectors totaling Y number of characters that is generating the limitation. In this example, I can get through 4096 elements with a red background before the 4097 element fails, because I have reduced the size of the individual selectors. The reduction must have some proportion to the number of selectors in the string, because just two selectors still allows 500,006 characters in one of them to still work for both. The 4096 number of may be the true "maximum" limit to the number of selectors, because when I reduce the selectors down to just two characters each (plus the ., ,, and spaces), I still succeed at 4096, but fail at 4097.


red


.


,



I find it interesting that this last test set failure happens near the 4095 number that Internet Explorer gives as the maximum number of selectors that can be done via the IHTMLStyleSheet::addRule method. It is apparently only a limitation of that method, because IE10 worked fine with the 4097 number mark in the test above, or any of the tests that Chrome fails in (none of which are using that method to generate the selectors). Why this nearness to that number given for the IE browser for Chrome's failure I do not know, but it is interesting.


4095


IHTMLStyleSheet::addRule


4097



There is no exact magic number, but given the above experiments, it does seem that there is some smaller character limit based on number of selectors to a selector size for Chrome as opposed to Firefox or IE10. It is apparently not the actual number of selectors, nor the actual total characters, but some combination between the two, of which at most it appears 4096 is the limit, but could be less if the selector string is longer (as the initial examples that failed after 1366.


4096


1366





Wow, this only gets more interesting... So I guess the bottom line is that if, for any reason, you go above 1000 or so selectors, you need to test really, really carefully. (Or break the selectors up. Or find another way of achieving what you want.)
– leo
Jan 1 '14 at 19:54





To me, it would be better to use back end programming to determine matches between year and countries, and then dynamically set specific class names for the color coding that you want on the countries for that year. Then you are just dealing with what, like 7 classes, rather than these thousands of selectors. (Of course, you have all the info already, so it would not have to even be dynamic, but it might take more time to set them up statically.)
– ScottS
Jan 2 '14 at 14:46





Optionally, if a country has a majority of years at one level, just put that as the default setting for the country, and override it for certain years only that are exceptions, which would greatly reduce the number of selectors.
– ScottS
Jan 2 '14 at 14:47






ScottS: Sure. The point here, though, is to allow third party users to add maps to their sites, and to give them a relatively simple way to color it. And static maps to allow for caching...
– leo
Jan 2 '14 at 19:00






@ScottS I have done some more tests and found whats the fuzz about. Check my answer
– Milos
Apr 26 '15 at 12:58



There is no maximum length for the CSS selectors. You can define as long as you wish. However, the important thing that should be taken into account is the file size.


file size



The max kb size that IE will read is 288kb, any styles after that mark don't get read.- Internet Explorer CSS File Size Limi


kb size


288kb



Moreover, the max selectors per style sheet is limited to 4095 css rules and 31 style sheets can be linked into a file - IHTMLStyleSheet::addRule method


4095


31



The last big issue is bandwidth. It seems that the css file is usually light weight. However, if there are 31 css rules which have very long names, it could slow down performance.





It is interesting that in my experiments with Chrome in my answer, that the maximum selectors allowed at best came out to be 4096, just one number off of the IE rule of 4095. But the IE rule also is only with respect to the addRule method, because in those same experiments (where I do not use that rule to generate selectors), IE10 is handling more than that number of selectors just fine. It just seems more than coincidental that Chrome fails near the same number in its best case.
– ScottS
Dec 31 '13 at 15:33


4096


4095


addRule






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard