> 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).
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.
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.
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.
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
Can someone explain the thinking behind this? Wouldn’t it be much simpler to have #id always override a .class?
The way it is set up currently that’s basically always the case (since 256 .classes are rarely used), but there is this weird edge case when as many .classes are used.
I don’t think it’s possible to meaningfully work with a rule like that. It just seems so non-sensical.
As far as I can tell from the specification posts here, it's entirely to make implementation more feasible. Rather than some complicated calculation of precedence, you can just assign each rule a single score. As long as the weird exception essentially never comes up (which is the point of specifying "a number system with a large base"), it's an efficient and sensible way to implement the desired rule.
The issue isn't in the base case but derived cases to determine which overrides the other. A div with an id that has another div with a class attribute should override anything done on just the div with the id? But when does the specificity of any chain of just classes become more specific than an id. That is why they have weights.
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
I recommend not using IDs due to selector specificity and the scenario where you most likely will run into annoying #ID issues and think about using `!important`.
I don't think it's absolute blasphemy to use #ids, but try to never use them. Think of it that way. I tend to use them only for #js-functionality hooks, which is also a good-practice to tell someone "don't freaking change this ID or you break the JS."
I'm obviously lacking in imagination here. How would using an ID for styling a "clearly one-per-page" element lead to problems? I'm thinking of things like the main page title, or some sort of primary navigation block. The whole point there is that I want the specific rules for those elements to override the defaults, right?
It may be "clearly one-per-page" now, but it may not be. You don't really gain anything by using an ID. Keep the selector specificity simple so it doesn't bite you in the ass and cause a refactor.
.page-wrapper
.page-main
%article.main
There's no difference using that to
#page-wrapper
#page-main
%article#main
Psuedo example, those can be mix and matched with classes and IDS but doing so just complicates the selectors and the cascade.
There is of course exceptions and things that may just make total sense, but overall, it leads to complications. You don't gain any real benefits unless it's a JS hook for #id selector performance.
I follow the same line of thought to an extent. I like to put an id on the body tag for global navigation purposes, but aside from that I keep the id for js work.
I'm experiencing that as well - it looks like any (unofficial) github buttons need to have their domain changed from github.com to ghbtns.com. The commit message seems to confirm this.
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.
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.
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.
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...
I just tried doing this with nested ids and it didn't work so perhaps this is for classes only. Might be worth trying layers of HTML tags also - see http://pastebin.com/7BhQdNAn
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.
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.
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 = 0x100