9 ms·
256 CSS Classes Can Override an #id
- victorNicollet 14y agoNice one. That's a bug I guess.
- mey 14y agoInteresting current versions of the following on windows fail - Firefox - Chrome - Internet Explorer 9 Opera shows the expected result though.
- revx 14y agoI got a red box, chrome 21 on win 7.
- dguaraglia 14y agoRed box on Chrome 21 on Snow Leopard
- simcop2387 14y agoI get a red box in everything but opera on linux. Seems to not be platform dependant at least.
- jlarocco 14y agoI get a blue box on Opera for Windows.
- yogsototh 14y agored box on Safari 6.0 on OS X Mountain Lion
- madprops 14y agored box firefox linux
- steve-howard 14y agoSeeing the same behavior on IE10 RTM as well.
- deleted 14y ago[deleted]
- omra 14y agoBlue boxes on all of the following: 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.
- whichdan 14y agoFor your sake, I hope this wasn't an actual bug you ran into :)
- prezjordan 14y agoI 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.
- yonran 14y agoAccording 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.
- mmahemoff 14y agoIt still works with > 256 classes. I was expecting it to overflow and go back to blue when I added a 257th class.
- SoftwareMaven 14y agoIf it is adding numbers, it may be losing the ID altogether. spec = classes + (id>>8) + (important>>16) + (styles>>24); If the assumption was that classes would "probably" be under 256 and wasn't put in a char, it could be messing with the whole value.
- croddin 14y agoCan you override an !important with 256 nested ids?
- Aaronneyer 14y agoNope, 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.
- 14y ago
- deleted 14y ago[deleted]
- chimi 14y agoI suppose someone should update this question then, because it looks like to me the limit is 255... http://stackoverflow.com/questions/4354921/css-is-there-a-limit-on-how-many-classes-an-html-can-have http://stackoverflow.com/questions/4354921/css-is-there-a-li...
- badusername 14y agoI 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 http://codepen.io/anon/pen/cKuBx
- zheng 14y agoThis seems to be taken from this answer on a question about HTML/CSS specificity http://stackoverflow.com/a/11934505/950912 http://stackoverflow.com/a/11934505/950912
- eykanal 14y agoThis 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.
- jnand 14y agoit's a feature not a bug. lol
- dayjah 14y agoobscure++
- lubujackson 14y agoPretty awesome find. I imagine it will have some outrageous use some day for someone.
- Cushman 14y agoStranger, perhaps, this also works with the same class 256 times. That is <div class="c"> with a style def .c.c[...256...].c {}. http://codepen.io/anon/pen/zbcxs http://codepen.io/anon/pen/zbcxs
- huxley 14y agoInterestingly, 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.
- eagsalazar 14y agoAn 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.
- solox3 14y agoI had the impression that class specificity (weight: 10) times 11 would weigh more than a single id (weight: 100), but I guess I'm wrong.
- d4n3 14y agoWeight 10 in a number system with a large enough base (e.g. webkit is using base 256). I think the intent of the specification is that 1 id is always more specific than classes for any practical number of classes.
- croddin 14y ago256 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 http://codepen.io/anon/pen/zefGg it turns red, but otherwise it stays blue.
- croddin 14y agoHere is a better example of ids overflowing: http://codepen.io/anon/pen/Khwon http://codepen.io/anon/pen/Khwon
- thezilch 14y agoMight depend on the browser, but Webkit-based browsers, for example, use a 0xffffff mask on the resulting specificity. And so... $ python >>> MASK = 0xffffff >>> MASK 16777215 >>> ID = 0x10000 >>> ID * 256 16777216 >>> ID * 256 & MASK 0
- gee_totes 14y agoAre you sure this isn't a bug with Codepen.io?
- nicholaides 14y agoIt'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.
- tracker1 14y agoI'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-specificity-of-css-selectors/ http://www.webteacher.ws/2008/05/19/tip-calculate-the-specif...
- sil3ntmac 14y agoNot a bug, probably just CSS's ridiculous selector algorithm. IIRC, the algorithm looks something like (100xid's) + (10xclasses) ...
- vigrant 14y agoIt doesn't seem to work when you switch the order of the css selectors.
- chacham15 14y agohttp://code.google.com/edu/submissions/html-css-javascript/ http://code.google.com/edu/submissions/html-css-javascript/ 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.
- gburt 14y ago[1] http://coding.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/ http://coding.smashingmagazine.com/2007/07/27/css-specificit... 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.
- nemetroid 14y agoRead 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.
- Osiris 14y agoOpera 12 displays a blue box while Chrome 21 and IE 9 show a red one. Another cross-browser incompatibility that we have to deal with...
- Foy 14y agoYay Opera! Also, if you're really using >= 256 classes in your CSS you may have more systemic problems than just cross-brwoser compatibility.
- duaneb 14y agoWhat base does Opera use for specificity?
- lastorset 14y agoWe 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.html http://lists.w3.org/Archives/Public/www-style/2012Aug/0493.h... for an illustration.
- lastorset 14y agoOops, should be base 25, obvs.
- StavrosK 14y agoProbably a large one.
- rplnt 14y agoThat'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.
- bingaling 14y agoWebkit source: http://trac.webkit.org/browser/trunk/Source/WebCore/css/CSSSelector.cpp?rev=81845#L63 http://trac.webkit.org/browser/trunk/Source/WebCore/css/CSSS... Specifically: 69 case Id: 70 s += 0x10000; 73 case Class: 88 s += 0x100; 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/layout/style/StyleRule.cpp#l521 http://hg.mozilla.org/mozilla-central/file/17c65d32c7b8/layo... 521 nsAtomList* list = mIDList; 522 while (nsnull != list) { 523 weight += 0x010000; 524 list = list->mNext; 525 } 526 list = mClassList; 527 while (nsnull != list) { 528 weight += 0x000100; 529 list = list->mNext; 530 } Same weights, Id = 0x10000, Class = 0x100
- CamperBob2 14y agoDid they mean to fall through to case Class in line 73?
- tlb 14y agoHe elided some lines, there is a break.
- deleted 14y ago[deleted]
- dclowd9901 14y agoFor some reason, based on the w3 documentation, I was under the impression that an id had an order of magnitude more specificity than a class. http://www.w3.org/TR/CSS2/cascade.html#specificity http://www.w3.org/TR/CSS2/cascade.html#specificity
- bingaling 14y agoI think it has _2_ (base 10) orders of magnitude more specificity. That's 10 times more specificity (than a single order)!
- nemetroid 14y agoHere's some of the specificity code from Webkit (right at the top of the file): http://trac.webkit.org/browser/trunk/Source/WebCore/css/CSSSelector.cpp?rev=121551 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.
- thezilch 14y agoIn the example, switch the order of the rules and the background will switch -- last rule wins, all things being equal. Not surprising... $ python >>> CLASS = 0x100 >>> ID = 0x10000 >>> CLASS * 256 == ID True
- mycodebreaks 14y agodoes that happen on all browsers?
- xer0x 14y agoAwesome! I can't believe this is trending on HN. But that is very cool.. Now, how is this useful?
- sil3ntmac 14y agoKnowing CSS's selector algorithm is useful as it helps rule out possibilities for CSS override situations. Edit: punctuation
- monsterix 14y agoOh nice! Bug at international level :-) Looks like it is some kind of stack and overflow in play.
- dfischer 14y agoI 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." Tips from http://www.betterfrontend.com http://www.betterfrontend.com
- Steuard 14y agoI'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?
- Inviz 14y agoFor example, styling the same unique block based on context. If it's a mainpage, I want it red, otherwise it's green.
- dfischer 14y agoIt 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.
- jamiecurle 14y agoI 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.
- arrrg 14y agoCan 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.
- Steuard 14y agoAs 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.
- bfish510 14y agoThe 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.
- troels 14y agoI'm surprised nobody linked to this yet? http://www.stuffandnonsense.co.uk/archives/images/specificitywars-05v2.jpg http://www.stuffandnonsense.co.uk/archives/images/specificit...
- sambenson 14y agoIt's not a bug, OP found out about it from my question on Stack Overflow: http://stackoverflow.com/questions/2809024/points-in-css-specificity http://stackoverflow.com/questions/2809024/points-in-css-spe...
- tosbourn 14y agoDon't worry guys, crisis averted: #id { background: blue ! important;}
- electrotype 14y agoAdd !important to the 256 classes too and they win.
- marksyzm 14y agoI 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 http://pastebin.com/7BhQdNAn