I guess the algorithm for specificity in all modern browsers involves a base-256 number. Why? I believe there are 4 slots for specificity - class, id, !important, and styles defined in the tag. 256^4 = 2^32, the size of an integer. Unfortunately we get this is as a side effect.
According to the CSS 2.1 spec, “Concatenating the four numbers a-b-c-d (in a number system with a large base) gives the specificity.” Base-256 is the obvious way to encode each digit efficiently, and I suppose all browsers that do this are still in compliance with the spec.
Nope, although I did find once you hit a certain number of ID's, it was something over 1000, not sure of exact number, it just ignores the rule altogether.
I don't think the class limit is 255, it is still a fuzzy number as the post declares. Here, I've modified the codepen to include another 256th class, and the CSS declarations on that class are applied to the element.
http://codepen.io/anon/pen/cKuBx
This is where this whole thing came from today. Somebody submitted this earlier, but it never got to the front page. I suggest a detailed readthrough of the question and all the answers for a great overview of how this works.
Interestingly, it doesn't seem like the classes need to be different for it to work, at least on Safari 6.0 if you change all the classes to .c000 it works just as well as having different ones.
An important side point: don't use #id unless you have a very very good reason and even then think twice. there is nothing more irritating than trying to refactor code that assumes and id input. This means you can't reuse that code to apply to multiple nodes at once. Same thing applies for both javascript and css.
I know it is semantically significant but in practice it is just hardly ever needed and frequently causes a royal pain in the ass.
BTW, performance is rarely a good reason either since by definition there is only one of anything that might be considered for an id so you can always find the element by class then save a reference to make repeated fast references.
256 nested ids seems to create an overflow. If you remove the #i000 at the beginning of the rule on this: http://codepen.io/anon/pen/zefGg it turns red, but otherwise it stays blue.
It's very unlikely. I can't think of a scenario where it could be changing the CSS and/or HTML that still leaves it syntactically and semantically valid.
I'm guessing that the implementation uses a 32-bit integer for calculating rule strengths as they apply to a selection. With that in mind, 8 bits used for each variable.. so it would make sense that 256 would overflow into the next value. see: http://www.webteacher.ws/2008/05/19/tip-calculate-the-specif...
The algorithm looks like that "in a number system with a large base". It is arguably not what the spec intended but probably acceptable in exchange for performance.
Read the spec instead. It says "in a number system with a large base". I suspect the unspecific wording is on purpose (to allow optimisation for sane conditions), but it should be fairly clear that the intent is that classes cannot override ids.
That's the sad thing about closed source software. Their implementation might be drastically different. I think they should write a blog post or at least a comment here about it though, I'm going to bug them now.
We use base 24, actually, but since we truncate before concatenating, we behave as expected here, unlike Gecko/WebKit. Obviously, a different TC that depends on one selector having more class names than another ("c" in CSS 2.1 6.4.3) will fail in Opera; it passes in GeckKit. See attachment at http://lists.w3.org/Archives/Public/www-style/2012Aug/0493.h... for an illustration.
and from irc: "in other words, its the size of the storage which matters and not really the base, other browsers seem to use 8 bits, we use 16" @shwetank
> Concatenating the four numbers a-b-c-d (in a number system with a large base) gives the specificity.
So webkit is using 256 as "a large base".
I only just read this spec a few months ago. For years I was under the impression that the spec was "1 point for an element, 5 for a class, 10 for an id", and the selector with the highest point value won...
Under the same impression too, I definitely remember reading this on a W3C advice/info blog (dark brown background, white and blue header - useful memory).
Basically, selectors are summed together with class selectors given a weight of 0x100, and id selectors given a weight of 0x10000, so this is a simple overflow. It's worth noting that a mask of 0xffffff is used, so using 256 #id's should give a specificity of zero.
97 comments
[ 3.7 ms ] story [ 114 ms ] thread- Firefox - Chrome - Internet Explorer 9
Opera shows the expected result though.
Opera 9.64 - FreeBSD 7.0
Opera 12.50 - Debian 6.0 & Windows 2008
Opera 11.64 - Debian 6.0 & Windows 2008
Opera 10.60 - Debian 6.0
Opera 10.63 - Windows 2008
Opera 9.8 - Windows 2008
MSIE 6.0 - Windows 2008
MSIE 5.5 - Windows 2008
So basically every Opera version and very old versions of MSIE.
http://stackoverflow.com/questions/4354921/css-is-there-a-li...
http://stackoverflow.com/a/11934505/950912
http://codepen.io/anon/pen/zbcxs
I know it is semantically significant but in practice it is just hardly ever needed and frequently causes a royal pain in the ass.
BTW, performance is rarely a good reason either since by definition there is only one of anything that might be considered for an id so you can always find the element by class then save a reference to make repeated fast references.
I think the intent of the specification is that 1 id is always more specific than classes for any practical number of classes.
Look at the css section. id's, classes, and selectors have weights which are used to determine which rule wins in the event of a conflict.
This is a feature, not a bug. Its called CSS specificity.
Although, the link[1] seems to suggest it should be 100, not 256... that might be a bug.
Also, if you're really using >= 256 classes in your CSS you may have more systemic problems than just cross-brwoser compatibility.
and from irc: "in other words, its the size of the storage which matters and not really the base, other browsers seem to use 8 bits, we use 16" @shwetank
Specifically:
id selectors are worth (0x10000/0x100) == 0x100 == 256 class selectors.This seems to be the mozilla source: http://hg.mozilla.org/mozilla-central/file/17c65d32c7b8/layo...
Same weights, Id = 0x10000, Class = 0x100http://www.w3.org/TR/CSS2/cascade.html#specificity
> Concatenating the four numbers a-b-c-d (in a number system with a large base) gives the specificity.
So webkit is using 256 as "a large base".
I only just read this spec a few months ago. For years I was under the impression that the spec was "1 point for an element, 5 for a class, 10 for an id", and the selector with the highest point value won...
http://trac.webkit.org/browser/trunk/Source/WebCore/css/CSSS...
Basically, selectors are summed together with class selectors given a weight of 0x100, and id selectors given a weight of 0x10000, so this is a simple overflow. It's worth noting that a mask of 0xffffff is used, so using 256 #id's should give a specificity of zero.