Don’t use ID selectors in CSS

Lately I have been testing out performance among css styles and I found that some of my very smart friends, started asking,”why aren’t you testing using IDs for the unique sections of the page?”.

This wasn’t a hard answer:

  1. The element is not re-usable on that page.
  2. This is the begining of a downward sprial into specificity
  3. Usually, IDs refer to something very specific, and abstracting would be tough
  4. Any performance gains picked up by using id, is negated by adding any other selector to the left fo that id

Lets delve into each of these issues at more length

The element is not re-usable on that page:

IDs are programmer’s equivalent to singletons.  There can only be one instance on the page.  This means there is no way to re-use it.  It’s usually a one to one relationship, and according to my speed testing, one line of css that’s only usable once is not a good value.  There IS a cost to css bloat.

This is the beginning of a downward spiral into specificty:

There are two main ways of overriding in css.

  1. The cascade: (anything further down the css, can overwrite the previous css rules)
  2. Specificity: the idea of creating weight by using weighted selectors.

The reason I say that specificity is a downward spiral is because the only way to overwrite a weighted rule is to add more weight..  plain and simple.  Now I am not just saying this because I heard it somewhere.  I have made and paid for this mistake.


.ModuleOfficeList .property-checkbox input
{display:block;margin-bottom:8px;_border:0px !important;}

.ModuleOfficeList .property-checkbox,
  .ModuleOfficeList .new-icon,
  .ModuleOfficeList .open-icon
{display:block}
...
.uid-officelistings .property-checkbox
{display:none !important; }

Above is real code from one of my own work from 2005.  As you can see, after awhile, I had to resort to some weighty selectors and the !important rule. This is very bad. Once we get to this point.. it takes us more time to hunt down the parent IDs we are going to use in order to overrule the current specificity. This is not team-friendly and definately not maintainable. Eventually you will specify yourself into a hole, and refactoring out specificity is nothing short of a nightmare.

On the other hand:

I have heard a few reasons why using IDs as selectors is a good thing. I’ll speak on them briefly:

Using ID selectors is faster
Yes, using ID selectors is faster than using class selectors for the simple reason that there can only be one id within a page. I even prove that is true, however the performance benefit is very small, and as soon as you add any other selector, the performance benefit is lost.


#profile-module {...}
#profile-module li {...}
.profile-module li {...}

The second selector is no faster than the third. That’s because CSS is read from right to left. so the
li
gets scanned first, which negates the speed of having an ID. Steve Souders explains how selector speed works.

IDs are meant for singletons
There are times when someone intentionally wants something to be used only once on a page. ID selectors would be useful for that purpose since they would signify once per page. My only argument here is my personal preference of having all my code be re-usable; especially since I don’t see CSS in a “programming language” way.

UPDATE: maintaible CSS / semantic HTML
There is a quite a huge following that believe using IDs are very helpful in creating maintainable CSS as well as creating a more semantic document in HTML. I think that Matt Wilcox sums it up best in his article about naming ID and classes properly. Matt brings up some valid points as reason for using IDs.

Update: Another Article advising classnames over IDs
A year after my initial post, Oli Studholme also made this post about ID selectors as well. We came up with similar conclusions. Thanks Oli!

Honorable Mention
It’s also worth mentioning, that I am not advocating getting rid of IDs from your markup alltogether. IDs can help speed up your javascript and they can relay meaning to your document.. all good things.

But in for CSS, I suggest not using id selectors. There are others that believe using id selectors do have purpose, however I dont find the good outweighs the bad. In the end, the choice is yours to make.

103 comments

  • Dave Gregory

    RR said: “And remember, there is not 1 way that will be THE way to do things”

    Well stated. I totally agree with that statement.

    AND WITH THAT. I think it’s about time to turn off comments. What could be said, has been said. Thanks to everyone commenting, and bringing your experience and ideas to the table. :)

    • Kevin

      No you don’t. An ID selector is for something specific. A class is reusable. You can’t use an ID more than once. You can use a class anywhere.

    • Randy

      If ID and Class were exactly the same then CSS wouldn’t have both. A class can appear multiple times in a web page, applying the same styling to different div’s on a page. An ID is a one time only styling, as the author said “a singleton”.

      • Dave Gregory

        Exactly right. Id’s and classes are completely different and also serve purposed beyond just css. They are significant and important in their own right..
        Thanks for the comments. :)

    • Dave Gregory

      Well, I dont think you can.. considering I use classnames over and over again on a page. see: “performance freebie”
      also, you aren’t able to “double id” as you are with classes. Therefore I can have a class=”box ext” which could extend my box with other elements. can’t do that with and id.

    • Nitin Reddy Katkam

      CSS classes and IDs may seem similar, but they are not the same – there are differences that you need to keep in mind when you use them. For example, you can use CSS classes instead of ID, but not the other way round.

  • Anonymous

    It’s CSS for godsakes. Simple markup, not “code”. It’s easy to change, and it’s nice to have some specifics when you’re reading it. With CSS, if it’s readable and it works, then it’s PERFECT. Anyone that says otherwise is an imbecile.

    You can’t just make a ridiculous blanket statement like “Don’t use ID selectors”. There are plenty of reasons to use ID selectors and even ID selectors with additional selectors to the right. Let’s say you have styles you want to apply specifically to one, and only one, area on the page… Why in the world would I want to junk up my class list with a class that only used one time?

    It’s a real shame there are going to be inexperienced morons coming to this article and thinking this is gospel.

    • Dave Gregory

      Interesting concept that css isn’t code. And no.. css isn’t markup. If you are going to talk semantics.. please get them right.
      You say it’s easy to change.. however I suggest that it’s not. Just as if you created a Class, with methods and properties inside it.. once that Class (see the capital C?), you wont just be going willy nilly and changing the way that Class/methods work. It’s the same with CSS if you do it right. Just like we strive to make our code re-usable in Ruby or .NET or Javascript, you want to do the same with CSS.

      And yes I can make a blanket statement.
      I’ll say it again.
      Dont use ID selectors in CSS.
      So you say there are pleanty of reasons to use ID’s, name one? I already addressed the Singleton idea, but I’m pretty sure you didn’t read to the bottom.
      Regarding people taking this as gospel, that’s up to them, however I’ve stated solid points and even changed the minds of some hardcore ID fanatics. Hopefully these “morons” as you say, will have read the whole article and will be better informed to make up their own minds.

    • Andres Roberto

      Obviously this anonymous guy does not have too much experience working with CSS. If you are going to use an Id you have to be sure that you actually need to do it. I personally use ID’s in order to make my markup a little more readable and for JS purpose. It’s a bad idea to use ID’s for CSS. I am going to read that Wilcox article and the other links in order to get better informed about this important topic : )

  • Marcos Zanona

    I think the ID selectors give you a very clear notion if that element is used only once on the page or not. it seems a bit confusing for me to have a class to the website footer, since you will obviously only have one per page. Sorry I am trying to get used to this idea, but it is really difficult for me to understand how this would organize better. Instead of using only classes or only ids why not use both and just make every selector fit you own purpose? I really feel lost when I view a HTML code and see classes everywhere, even for items that are supposed to be used once :(

    • Dave Gregory

      Two things.
      1. You are absolutely right about the footer. That could be used once. and be done with it. That would be a perfect example of a Singleton… however

      2. The thing about using classes instead, is the idea behind OOCSS. Create re-usable chunks of code. For example, if you have columned footer, then why not use your grid css to create the columns. You have just re-used CSS in an area that seemingly would have been a singleton. The idea is that you look at your site for similarities.. and create re-usable chunks for them. When you see a variation on what could be a similarity, use the re-usable CSS and extend it with a second class. Kinda like prototyping in javascript.

      So just like in programming, Singletons are likely rare and are intentional. Same goes with CSS. I use ID in very rare cases, but usually even at that.. I haven’t found many occasions where I absolutely want something to be styled on the page only once. If I can abstract the CSS and get multi-use out of it… I will.

      • Matthew Toledo

        Ugh… OOCSS. I wish that trend would die. All it does is cause you to pollute your HTML elements with one to up to a dozen classes. So that becomes That’s the reason why I think OOCSS was invented by recent programmers who don’t remember the pre-2000 horror days of font tags and span abuse. All OOCSS does is move positioning and display elements BACK into HTML where it does not belong. OOCSS is a step BACKWARDS. I could rant on about it for a while. But basically, OOCSS forces future maintainers of your CSS to learn some arbitrary meta-language that first guy created, it is not semantic, and in the long run, after many other people maintain the code, it doesn’t stop CSS bloat or specificity wars. Plus, Firefox and Chrome let you edit SCSS in their developer tools today. I’m fairly sure that in a few years, they’ll support SCSS natively and you can just use mixins and functions to replace all that OOCSS gobbledygook.

        • Dave Gregory

          Actually untrue. If unused correctly.. of course OOCSS could do just the same. if you are making classes named “right-justify” then you are doing it wrong. The name of the game is abstraction. Making lego-like CSS components that can be used over and over again, but NOT just one or two styling elements.
          Also not a trend. It’s just another way of thinking when creating your CSS and I’m pretty sure it’s here to stay.
          Lots of people love using it and love the positive outcome of it. That includes me. :)

          • Rob Riggs

            Thanks for the great article. I’ve been reading up on CSS abstraction and OOCSS for a while now, and I’m ready to start implementing it into our current Web app.

            I must admit, I’ve been guilty of the exact things that are now considered bad CSS programming: too many Id’s and cascades for specificity, and not abstracting.

            I’m still trying to figure out the best CSS coding pattern for me, between using Scss and OOCSS.

            I’m really looking for a site with excellent CSS code that I can review that follows these principles.

            Can you recommend one? Thanks.

          • Dave Gregory

            Heya Rob

            So uh.. well I have a good example set of stylesheets.. I’ll look for them. (from an old, internal site) They use SASS and OOCSS. (they both work together very well, if used wisely. I’ll look for them and get back to you.
            Til then, the Starbucks website uses oocss from my understanding. Here is their styleguide. Check out the pages within to see some of this, working.
            http://www.starbucks.com/static/reference/styleguide/
            One thing to note, however, is that OOCSS is less of a CSS library or framework, and more of a concept. I suggest watching Nicole Sullivan’s videos about OOCSS. It makes far more sense afterwards.

  • Graham

    @Dave: “So you say there are pleanty of reasons to use ID’s, name one?”

    Your article logic conveniently ignores that ids are very useful for organizing stylesheets semantically.

    e.g.

    #footer .special-part ul { }
    #footer .nav a { }
    #footer .title h3 {}
    etc.

    By definition, the “singleton” nature of ids allows one to easily pinpoint what a particular set of styles is defining. In a complex layout, this is a MUST. It may be technically redundant to include the id selector, but it’s a whole lot more efficient for human eye/brain — which, if you ask me, is really what counts with stylesheets. If you want efficiency, just minify all your CSS be done with it. Until you need to go back to the source to change something… Then your semantic organization is what matters.

    Are you really advocating that one should only ever use classes?

    Honestly, that’s pretty ridiculous.

    1. It’s a given that common elements classes like “.title” or “.nav” will be assigned quickly. So without using ids, how do you specify specific elements? More classes with .really-long-and-arbitrary-class-names-like-this-just-be-unique? Are you really suggesting wading through umpteen levels of nested classes, just to figure out which value is being applied where, is more efficient than #right .here .it .is {} ?

    2. I get the concept of reusable styles, but there is a time and a place for this. You seem to be applying this relatively specific use to one dogmatic general practice, outlawing id selectors as if they are “bad”. I second @Anonymous comments above. Ids are perfectly valid. When did they become the enemy, as you advocate?

    • Dave Gregory

      The problem with IDs are they introduce specificity.. and weight to your CSS. In terms of re-usability, this is a huge issue. Any time you want to override styles that use ID selectors.. you will need to add more weight to the selectors. That’s a slippery slope.
      I’m definitely not suggesting long arbitrary names for css. Just names that make sense, and are abstracted enough to make sense what they do. Again.. being specific pigeonholes them and reduces their ease of use.
      ie.. you wouldn’t want to name something .home-display for a list of images. you would want something more abstract.. ie .inline-image-list or just .inline-images or .inline-list. That can therefore be re-used without being some arbitrarily long name.

      • Chris Eppstein

        It’s not a problem that IDs have more specificity. It’s feature not a bug. When I style with IDs I WANT those styles to be more specific. If you only use classes then you only have two mechanisms to resolve cascade conflicts: document order and !important. Specificity, when used correctly makes styling a website easier to maintain.

        • Graham

          @Chris: EXACTLY. Specificity is the whole point of IDs. Like you say, if you use only classes, you run into situations where you have to come up with needlessly “creative” ways to be specific when needed — e.g. unique class names, multiple/redundant override styling through doc order, or worse, abusing the nuclear shotgun approach that is !important.

          @David – Ya, speaking of slippery slopes, what do you call “Just names that make sense, and are abstracted enough to make sense what they do.” ? — At what point does that get absurd? Why do I need to come up with several unique “names that make sense and are abstracted enough” for classes when I could just write #id .class tag {} and be done with it? If a site is at all complex, it’s inevitable you will need to introduce some semantic specificity into the class names (yes, “.home-section-subsection” blah blah), because the single class name abstraction will rapidly become very vague and confusing.

          What’s worse, using a simple ID tag, or having a .six-point-hyphenated-class-name?

          I’m sorry, but this war on IDs in styles seems like a trendy fad to write anal retentive blog posts on, rather than a legitimate practice to promote.

          Classes are great, but IDs are not the enemy.

          • Dave Gregory

            I dont know about a fad; especially since I wrote this a year ago. Actually, this post stemmed from a conversation Chris Eppstein and I had back then. Suddenly, the CSS Lint tool came out and my blog post was resurrected from the dead! So fad-ish? No. I’ve been using this concept for quite a while now.

            What’s more beneficial to a-classname-with-lots-of-dashes? Well I wouldn’t say lots of dashes are a requirement to a classname. In fact, that might get away from abstraction. However, a classname is still ten times less specificity, no matter how you name it..
            Therefore, using a classname, however absurd you make it, will still carry less weight and will not override the cascade.

            Abstraction is tough. What do you name your methods? Do you make them specific so they dont make sense if you try and use them elsewhere? Or do you think about sensible names that explain their purpose in a way that’s sensible? I believe the same can be done with CSS. Now I agree, it’s hard making names that are abstracted, yet can still convey something useful to the developer. That’s the toughest challenge about it. But that’s why you can use so many other ways to convey meaning.. IDs, data attributes, html5 elements etc. I tend to comment my code in a meaningful way that conveys what the css does, as well as an example of the code if need be.

          • Andres Roberto

            Too much specificity will ruin the cascade. Yes, IDs are not a bug, they are a feature, but if you use them in a bad way, you will do bad things.

            And by the way, I don’t care to use six-words-classes like .social-link-list-item. What’s your problem with long names? : )

    • Dave Gregory

      I wouldn’t call IDs the enemy per se, however I would suggest against them, and if used, they should be used with the full understanding that their specificity weight will not be easy to override using the cascade. It will require cascade + specificity.

      • Zen Thomson

        Sorry but I can’t understand why would anyone debate against functionality. I’m not afraid of using IDs where they meant to be used..if you know the language enough (and to be bold css is not a hard one) it’s a feature they built for a specific reason, and I can’t see why wouldn’t you use it what it is good for..
        You don’t seem to understand the specificity css offers. I see why re-using code is good, but that’s not the ultimate practice, and not even the only technique you should use in your code. Even if you like it there are some things that require other methods.
        IDs serve a purpose, and I wouldn’t want to mislead people believing otherwise.

        • Dave Gregory

          I hardly think I am misleading anyone. As I said in my article. The choice is yours. However, I give you the information as to why using IDs aren’t the optimal idea for re-usable css.
          You say I dont understand that specificity that css offers; I suggest you look at it this way. What benefit does specificity offer? If you take advantage of the cascade, there really isn’t need to override your css further down the page; especially by using something so weighted as IDs, or even using more selectors, which just make your code more brittle.

          • Graham

            “I hardly think I am misleading anyone”

            Frankly, I disagree:

            “Don’t use ID selectors in CSS” “using IDs aren’t the optimal idea for re-usable css.”

            Yellow journalism FTW.

            I mean, congrats, this post and others are generating a lot of traffic and discussion, but I honestly haven’t been convinced yet there is anything being said here that is revolutionary.

            Well optimized CSS will include a mix of classes and ID selectors as needed based on the specifics of the layout. There’s cases where specificity is essential and cases where reusability is.

            Speaking of brittle code — let me give you an example of where specificity matters:

            Let’s say someone follows through on your suggestion to only use classes, and falls in love with the newfound reusability of their uberflexible styles. They discover that it’s much more “efficient” to reuse cascading styles to create the desired styles for their layout, using a mix of general, abstracted styles and specific-by-class-name classes, usually with multiple classes like class=”this that this-too”. The layout is finished, and it’s a thing of beauty.

            Fast-forward 6 months. Our styles artist has left the building and someone else is brought onto the project. The homepage on the site is to be redesigned to add few new widgets. The new dev attempts to introduce these changes, but discovers the homepage layout is, in fact, a complicated web of interdependent, cascading classes. In fact, many of the general, abstracted class names were named based on assumptions about the homepage layout that are now, at best, out of context, or at worst, just wrong.

            So the new dev has to go through and scrub these classes to remove redundancies, overrides, awkward class names, or assumptions for the corners this “reusable” approach has lead into.

            The only cases where any solace is found is where classes were used with specificity in the names — LIKE IDs.

            Moral of the story? Use the right tool for the job.

            If you have a general style, like “float:left;”, sure, create a .left class and paint your layout red with it. But don’t rule out IDs for their exact intended purpose: specificity.

          • Andres Roberto

            @Graham:

            “using IDs aren’t the optimal idea for re-usable css.” – That true, it’s no optimal for… re-usable css…

            Man, don’t float to the other edge if you know what I mean. It’ not about creating a lot of useless classes, it’s about making easy to create similar elements on a huge scalable web app.

            If your example guy want to change things, he just has to change the classes. Any way, if it is a unique element that will not change, maybe it’s ok to use an Id, why not? But for example, let’s say you have a main horizontal navigation bar. You could have a .h-menu class, that you could use for any horizontal menu you will have in your app. It gives layout properties to ul and li elements that has that class. You can create a nav#main-nav with an ul inside with the class .h-menu. Oh no! This menu is not going to be horizontal any more! Well, let’s take h-menu class out! and let’s add the .fixed-menu class that the last guy created : ) Thanks old guy that use re-usable classes. So stop fighting against reuse, because it’s as important for CSS as Data Structures are for Programming.

    • Andres Roberto

      Well, I am not agree with you. CSS abstraction is really important. I work everyday on really big scalable web apps, and it’s very important to me to do reusable CSS modules in order to easily create similar elements in new sections of the app. You don’t have to use long and unmeaning names! That’s your fault if you do so. Use class names like .horizontal-menu, .social-links, .icon, and so on.

      Oh, and by the way, I am not agree with the idea of semantic ID and class names. Yes, they should have a comprensible name that indicates what they are. If you don’t, you will not understand what they do, but they will not actually have a meaning for the machine.

      If you like semantics, use HTML5 tags, meta-data, etc, but don’t think you are a semantic guy because of your IDs and classes names.

  • Bradley Wright

    I’m afraid I cannot possibly agree with the advice given in this article. The rules and semantics of the rules are very simple: if you have one specific thing on a page (a masthead; a user profile card; a login box) use an ID. It has a specific meaning: “the single profile card object on the page”.

    If you’re building a flexible modular system driven by a CMS you’ll probably use classes more, or you have more than one of a type of thing: a list of events; a carousel; a primary and secondary submit button in a form.

    Both of these things are common sense. I don’t know why we need to have specific and blanket rules discouraging IDs, or (yet to be heard, but to my mind as likely as this current argument) against classes.

    As for specificity as an issue, that’s just how CSS works. If you know what you’re doing I can’t see the issue here – I’ve certainly never been bitten by any “over-specificity” issues. I just use CSS and HTML together as designed.

    • Dave Gregory

      Lucky you! I have definitely been bitten by the “over-specificity” bug. It hurts bad!
      So you talk about a login box right? You might ID that because there is only going to be one login box on the page.
      Look at the login box differently; is it a login box (one on page) or is it a label and text input below it… (or next to it). Now it’s gone from something seen only once, to something you will likely see everywhere on the site.
      Now if you have put these styles in #login-box, you have removed any chance of re-using that code on the site.
      what about using .block-form-layout on the form, and have styling for all elements inside that class? now you have a full featured style guide for your form elements across the board. Better yet, .block-form-layout.ext can be used to “extend” the styling and allow for exceptions to the rules. (as is usual for design)

      • Ben Hull

        If you put the styles that are generic inside an ID-based selector, you’re doing it wrong. There’s no reason that the #loginBox can’t have it’s style provided by rules from both specific and generic selectors.

        Your selectors should match your *intent*: if you mean for a style to affect only the form elements inside the singular #loginBox, then that’s how you write your selector. If you mean for the styles to affect all form elements, then you write a generic selector, based on classes. When you write selectors that way, you don’t get bitten by over-specificity – as Brad says – they just work when you use them as designed.

        If you find yourself using classes like .block-form-layout, you’re also doing it wrong – your IDs and classes should describe the structure of the data, not the way it will be laid out, even in general terms.

        • Dave Gregory

          Why? Why should your classes describe intent? Is there any reason, other than giving yourself the warm fuzzies, that we should be classing with *intent*? I’m not trying to be snarky; it’s just that all the things that we have held so dear to us in CSS, have always been the biggest pain as well. Classes are functionally and semantically benign. The are useful hooks for us as coders. Whether it be javascript or css.

          Now I am just saying that we should question the usefulness of matching intent with style. So if you have a section that is styled EXACTLY the same as another section, but they have no similarities in function, why would you NOT use the same classname in order to re-use css?
          I am not advocating use of classnames like “red-border” which actually makes no sense. That’s not abstracted and is far too specific; limiting the extent of the styling.

          I think Nicole Sullivan sums it up best here:
          http://www.stubbornella.org/content/2011/04/28/our-best-practices-are-killing-us/

          • Dustin Dikes

            The only reason that you should need for describing intent is semantics. These arguments are all focused on CSS and completely ignoring the underlying HTML.

            When you write HTML, it is bad to generically add classes to elements for the sole purpose of styling them across the board. The ids and classes for elements need to indicate what they are, not how they look. You are blurring the line between semantics and styles.

            In the case of the login box, you were mentioning that it could just be a generic form class so you can add that same generic form class to other forms across the site. The way I would do it is have some generic styles for the input fields without any classes or ids attached to them (like background color, border, etc). Then I would have #login-box and would specifically target the inputs inside it to add any extra styling that will differ the #login-box inputs from any other inputs on the site (like, for instance, the width of the input fields).

          • Graham

            I agree with @Dustin.

            David, you rally against “over-specificity”, but what about “over-generality”?

            IDs restrict the scope of a given class to a particular part of the page. There is absolutely a time and a place for that. The particulars are up to the designer in how exactly to slice it up, but I just don’t think one can argue that specificity is never required — at which point using classes to mimic specificity because “IDs are bad” is just silly.

          • Andres Roberto

            Hey guys, selector names have 0 semantic weight. It the same for the machine if your class name is .login-box or .island, etc. Please, stop fighting against the world!!! You want to be semantic guys? Use HTML5 tags, RDF.

          • Aidan Jalali

            Andres, ‘semantics’ is anything to do with ‘meaning’. Browser semantics and human semantics are two sides of the same coin. Class names DO have semantic weight, but from a human perspective, not a browser perspective.

            E.g: Giving an error message the classname ‘red’ instead of ‘error’ is bad semantics, because it describes the appearance of the element rather than the meaning. What if you wanted to change the color of ‘.red’? It doesn’t make sense any more. It still WORKS, but it doesn’t make sense.

      • brad

        I feel like you have mentally built an optimally generic log-in box. I agree with the reusability of thinking the boxes content as “label and text input below it” etc. But, from my experience, I’ll usually have a log-in box in the header, that’s floated to the right, has a drop-shadow, different bg color rounded corners, and a specific width. And the styles really couldn’t be used elsewhere.

        Going id-less i would have something like <form class=”float-right drop-shadow-black bg-red rounded-corner-5 width-narrow”>. That just seems a bit excessive to me. (class names presentational for example purposes).

        • Dave Gregory

          Having that many classes would be bad. Also classnames can be abstracted so they neither describe specific styles, nor describe the content inside them so specifically.
          ie: “home-information” vs “float-right red-border padding-sm” vs “information-module”
          The latter being the best strategy in my opinion, as it explains what the content does, however isn’t so specific. This allows consistent design as well.

          • brad

            See this is where I’m torn “information-module” seems so nebulous, it could apply to almost anything. While it would be more scalable, I feel like it would also be more difficult for another developer to understand exactly what that refers to.

            I think a consistent design is also very helpful. I seem to receive designs that often times has elements that follow no pattern and are seemingly random.

            Do you have a couple of sites you’ve done, aside from this one, whose code I can examine to get a realistic sample to study?

          • Dave Gregory

            @brad
            You are right.. “information module” is nebulous and makes it a bit tougher for other devs to just grok what you are talking about. Documentation would be the fix for that, but yes, that’s a downside.
            Another tradeoff. Having good code with a “1 to many” relationship seems positive enough to outweigh less descriptive classnames.

            Oh man you hit that nail on the head! Consistent Design! I’m gonna make an article all about that. Consistency is not only key to good UI, it’s cleaner, and it cuts out “one trick pony” css that’s only meant to adjust code to the designer’s whim. This is the hardest part of doing a re-design; kicking back everything that’s just slightly off, or a few pixels different. We have H1 to H6. There is no reason why there needs to be slightly different styles for similar headlines. Margins? There can be standards there too.
            I just finished re-designing our internal site to conform to a style guide. One that I suggested and got the designer on board as well. I kicked back every time there was an inconsistency, but after awhile.. we had it! A design, that had less than 5 lines of single use css!
            Unfortunately I dont have a site you can check out. The one I am speaking about, is internal. Maybe I can send you some of the code privately. :)

          • Graham

            @David, re: “information-module”

            That’s exactly what I meant in my comment above that “general, abstracted” class names get vague and confusing very quickly.

            Seriously, how ridiculous is this going to get?

            I don’t want to work on a stylesheet by another dev that reads like a philosophical treatise. I just need to know what rule is defining what style, where.

            @brad is right, more often than not, if you are targeting with specificity, it’s because the element you are targeting IS unique. And, you know, even if it’s not 100% unique, it will be a heck of a lot easier for other devs to deal with than deciphering what the heck cryptic class names like “information-module” mean. I’ve stepped into code like this before, and I HATE it. Needlessly arbitrary and esoteric code always strikes me as something Microsoft would do (ya, I went there).

            Just follow Chrome’s Web Inspector format. Seems to me like they’ve nailed it… There is never any mystery about which style is being matched. In my experience, the closer your own styles reflect Chrome’s interpretation, the easier they are to manage.

  • sasklacz

    u say there’s no performance gain. Try selecting dom element with javascript with and without id. Good luck.

    • Dave Gregory

      Well, that’s javascript. Javascript selector performance is very different than CSS. CSS reads from right to left in terms of selectors.. and javascript can be scoped for performance.
      In jQuery, you might do $(".classname") or instead you could scope with $("#scopeID").find(".classname") which will improve performance.
      This is something not possible in CSS currently.

      • Rey

        must agree with sasklacz as there are advantages to use id if the website is javascript heavy. Totally abandoning the id is not the right course, but using it less and using it properly would be the best solution.

        • Dave Gregory

          I never advocated getting rid of ID from your HTML, however I can see why it seems like I did. Thanks for pointing that out. I should have mentioned that in the original post. I’ll update my post to reflect that I’m not suggesting getting rid of IDs alltoghether.

  • Liam

    I still don’t think this is a hard rule, I use classes for most things, and always have done, but there are cases where an ID makes more sense from a maintainability, logical and semantic point of view.

    If you find yourself having specificity battles because you use ID’s the answer is not to stop using ID’s completely, but to learn where you were making mistakes causing specificity issues and to address those mistakes.

    You don’t want selectors like
    #home #content article .author .details .name a {
    /* something *.
    }
    This doesn’t happen because of the use of ID’s, this happens because of a poor understanding of CSS from the majority of people.

    • Dave Gregory

      This sounds like a future blog post? Seriously, I’d love to hear how the use of IDs, from a maintainable point of view, outweigh the downsides of added specificity. Please elaborate.

  • Isofarro

    “The reason I say that specificity is a downward spiral is because the only way to overwrite a weighted rule is to add more weight.. plain and simple.”

    Incorrect. You can use the same specificity and put your overriding rule after the rule it overrides. No additional specificity needed.

    • Dave Gregory

      Okay yes, sorry for not explaining myself so well. However that still ends up bad. This means in order to override a style you will need AT LEAST, the same specificity and have it be further down the cascade.
      I still find this disturbing and eventually leading down the specificity spiral, ending in !important

      • Isofarro

        “This means in order to override a style you will need AT LEAST, the same specificity and have it be further down the cascade.”

        Having the same specificity doesn’t by definition result in a downward specificity spiral.

        Sure, you override something after it’s been declared. That’s generally how inheritance-based systems work. Developers already naturally understand that. CSS suits a pattern of styling from least specific to more specific, working against that grain is plain silly.

        How is overriding something that hasn’t yet been defined going to be logical or maintainable to anyone other than the original author?

  • Hector Hurtado

    Somehow, it comes down to this:

    1- just code! I love metaphysical (hmm, metadigital) theories, but if they stop you from actually starting the job, just go ahead and start typing — wow, I can’t believe I’m writing this, I love conceptualizing forever.

    2- once you see properties repeating, patterns emerge. It is time to refactor — surely, with classes.

    3- keep refactoring until you find a balance between:
    a) usability: do I really need to single out this repeating property by creating a class?
    b) reusability:can I easily reuse this? Will I?
    c) readability:Is my code accessible to me today? To me in 6 months? What about others?

    Now, I tend to side with Dave if and only if you have an Object Oriented mind. But this is not a trivial, background matters… Designer, developer…

    To wrap up, since I mentioned OOP, I’ll finish with this: Don’t Repeat Yourself (DRY) and…

    The more tenuous the relationship between two concepts, the more loosely coupled they should be. Conversely, the more closely related two concepts are, the more tightly coupled they may be.

    Keep coding!

  • Andreas Lagerkvist

    Personally I almost **never** user .classes. Every module simply gets an ID around it and then I use SASS mixins to style those IDs and its descendants. I keep each module styling in its own file and mixins in categorized files (lists.scss, forms.scss, icons.scss, etc). That way I can be absolutely sure that if there’s a problem with the “recent comments”-module, I’ll find the code (and _all_ the code) in the recent-comments.scss file. Changing things in that file affects _nothing_ outside that module.

    I find working with generic classes a lot really makes the code difficult to maintain. I really hate it when I need to give an element a class in order to style it, and that class has already been styled by someone else for a completely different purpose. Now I have to re-name my class or re-style it specifically for my module.

    Another annoying thing is that when everything is styled with classes, you can never, safely, change the styling of those classes without going through the entire website to make sure you’ve double-checked every element that uses that class (by searching for it in the generated HTML I suppose).

    Third negative thing about styling with classes is that it absolutely ruins your markup.

    • Alwaison

      “Changing things in that file affects _nothing_ outside that module.”

      So, if you must to add a bullet in all the lists of your website, you need to change it in all the css files? Wow, thats make the code very easy to mantain…

      IDs are not the devil, but forget about the classes, seem very risky for me…

      • Andreas Lagerkvist

        I always style elements on single element selector level (ul, h1, p etc) in a way that I most likely want them to look unless something special is going on. I don’t use reset stylesheets but instead give all elements some basic styling that looks good on its own.

        When I need a list _not_ to have bullets or be on one line etc I simply go:

        #navigation ul {@include plain-list;} or #navigation ul {@include pipe-separated-list;} etc.

        So no, I don’t “if you must to add a bullet in all the lists of your website, you need to change it in all the css files”.

        In fact, since I basically just replace .classes with @mixins I code pretty much exactly the same way you would with .classes except I apply my “classes” in my CSS rather than my HTML, which, obviously, keeps my HTML extremely tidy.

        The only time I specifically style an #id or any of its descendants is when that styling is _only_ used for that module. If I write CSS I think I can re-use I turn that CSS into a @mixin.

        • Rhys Lloyd

          Okay, I know I’m raising the dead on this post – but using mixins to replace classes? Your stylesheets must be huge! Sure, it looks small and I’m sure it’s maintainable through the power of SASS – but even the minified CSS output would be substantially larger than if classes were used smartly in a modularised fashion.

          • Dave Gregory

            Actually, I think that’s a good point. I need to test out minified code using @mixins over @extends instead. I was pretty shocked to see that mixins compress extremely well. They arent something I like to use often either, so I wonder how that will fare.

  • LATerry

    Sometimes it can be difficult to distinguish someone being a contrarian for the sake of being contrarian, or someone genuinely bringing up a new angle on a topic. I have to say though that I am warming up to some of your ideas. I guess I will try apply them on a future small project, and see how it feels.

    • Dave Gregory

      Thanks. I am definitely not trying to just argue for the sake of it. :) I think there are valid reasons for removing IDs from your css and I’ve been doing it for about 3 years now, with no issue. As you can see, I have tried to test and find possible benefits of using ID and the ones I have seen so far, dont offset the issues I have with ID. Thanks for the input!

  • jorge

    I think you should post an example that explain your position. Like: we have this homepage with ID selectors, implementing this new css code without these selector works better. and so on…
    PS: Think about the newbies like me!! :P Would be nice!
    Cheers!

    • Dave Gregory

      Hah! Took someone long enough! However you tried to take a jab, but you did it wrong. I’ve never stated there is anything wrong with ID in general.. just not to use this in css. Good try.. I guess?

      try this at me instead:
      “Yo Dave, you suck! I found over 300 selectors using ID in your CSS! Three hundred! You should eat your own dogfood you buttface! ”

      Okay so NOW I am properly burned.
      That’s when I’ll give you some lame excuse like “leave me alone! I use a wordpress template and I dont roll my own, too busy working etc etc.” something like that.

      So when I actually do refactor my own blog, I’ll KEEP ID’s because there’s nothing wrong with ID’s in themselves. I will however, remove selectors that use ids. There.

      Good job checking my code. You are the first to mention it. (maybe not the first to check) :)
      I’ll get to it when I have time. meh.

  • clonyx

    Regarding a loginbox I’d rely on something like:

    #loginbox{
    styles related ONLY to the component…
    }
    #loginbox .form-box{
    the base component for reusable form elements…
    }

    IDs are created for valid reasons, and the code above describes how the components works even if it is the first time you see the code.

  • clonyx

    Mistake in the last post… I meant:
    #login-box{
    styles related ONLY to the component…
    }
    .form-box{
    the base component for reusable form elements…
    }

    And my HTML would be coded as:

    • Dave Gregory

      That could work.. however why not just extend the login box with an extension classname.. .login-box.form-box {…}
      which allows you to extend form-box without affecting it.. AND you get free re-usable code by using a class.

      • Andres Roberto

        That’s right. When working with web apps you don’t know when you have to create one more login box, just because your client asked to do so or because you just really need to do it!

  • NOT-mozilla

    You’re doing a disservice to anyone reading your article that may be new to CSS or trying to get a better grasp of how best to use classes and ID’s. A blanket statement and an article title of “Don’t use ID selectors in CSS” is an aphorism solely designed to generate traffic and to boost your own self-esteem. ID’s have a specific purpose and using them in a layout, frankly just makes sense. Reusability has obvious benefits but so does specificality.

    I hope that novices and beginners don’t start subscribing to your opinions and end up creating far more work for themselves and others who may have to maintain their code in the future.

    Just because there’s a way to obfuscate CSS doesn’t mean it should be done. I guess those of us who use ID’s will never be 31337 in your book but when it comes time for making an edit, those who subscribe to your opinions will be scanning hundreds of lines of code trying to figure out dependancies and their implications while those who used ID’s for their intended purpose will already be home.

    • Dave Gregory

      Please use a real name instead of a generic name like Mozilla. That reflects negatively on your comments and I haven’t even read them yet.

      • Dave Gregory

        Interesting that you believe just by NOT using ID’s, that we are creating MORE code and MORE work. I am advocating the opposite. Creating re-usable CSS using classes allows you to make LESS code and CLEANER code.

        nice try tho Troll.

        • Erik Reppen

          In a large team on a complex site scenario, yes you would be. General tag CSS should be easiest to override. Classes should represent re-used containers and special case tags. Any unique container, not likely to get used twice in future layout tweaks should have an ID. And no, you should not use that ID every chance you get, you should use it sparingly, only for properties that you need to override within that unique container.

          What you end up when nobody uses IDs is a CSS class arms race every time you narrow down to more specific code and when you get one rookie on the team who doesn’t get the generally idea is minimalism, not fear of specificity, they start tacking on 5 css classes to everything they write so nobody “breaks their stuff.” What would you rather override? #sub-nav button or .main-section .sub-nav > ul > li > button.nav_button

          The question isn’t whether to use IDs, it’s how to use them competently.

      • Erik Reppen

        CSS breaks for different reasons including changing the wrong classes. It can also break easily due to their not being specificity applied when it made perfect sense to do so. Example:

        Most of my button properties are defined on a simple button tag. But my sub-nav buttons need a couple property tweaks.

        is:
        #sub-nav button
        or:
        .sub-nav button

        the smart way to do that?

        Remember this point in decision-making right here. Well call it Point A. The author of the class version knows it would be pretty easy to smash .sub-nav button as there are two more general containers above it with classes so they add some things:

        .main-content .side-bar .sub-nav button

        Now somebody needs to override a property on that sub-nav with CSS that is only linked on a special page-type.

        .main-content .side-bar .sub-nav > li > button

        To me, a selective ID-user, that is a freaking mess that could have been avoided. If the sub-nav overrides had been set under an ID in a non-distant ancestor like #sub-nav button, we would have never moved beyond Point A in the first case and when it came time to override #sub-nav li button would do the trick just fine.

        The key to flexibility and maintainability in CSS is minimalism in CSS. Not using IDs at all is just as good of a way to start a CSS arms race leading to a convoluted bloat-fest as using them badly is. IDs are for very specific styles narrowed down to the immediate container so that you can do whatever you want with your more general styles and not worry about unanticipated breakage in those specific areas.

        If you believe classes-only is the way to go, you’re failing to understand a crucial point in CSS. You don’t define everything on one bucket if you can avoid it. The more you inherit from more general styles, the better. The less you have to worry about breaking highly specific overrides to those general styles, also, the better.

  • Andres Roberto

    Ok, Stop fighting against what’s very accepted by the most of the Front End community. Id’s are not a good idea for styling. They can help you in some cases because of they specificity power, but that’s does not means that they are the solution for every single element! Stop fighting against reusability and stop fighting against big names and STOP thinking that classes and ID names really give any meaning to your markup! The only one that will read them is the guy that maintain the website! Machines ignore them. I will say it again, want to be semantic? OK, then use RDF and HTML5 tags and a lot of Semantic Web Stuff: http://www.w3.org/standards/semanticweb/

    • paolo poggi

      I think we’ve heard you the 2 (or were they 3?) previous times you stated this. I’m trying to reach the bottom of this post :)

  • Anthony

    ( I might have disagreed with you in an earlier comment, however … )
    I am finding myself using class for almost everything now.

    It is great for ‘context’ when more than one developer is hacking away at the style sheets, and it decends into the usual mess. Eg for a price:

    #cart .price {
    }
    #cart .name {
    }
    #cart .qty {
    }

    #mini-cart .price {
    }

    .product .price {
    }

    Then all developers can obviously see what is being edited, there can be more than one name per page without conflict, and names can be short.

  • Jack L

    I have come to the conclusion that IDs are not all that necessary in CSS. They are as Dave repeatedly suggests useful and even necessary in HTML, which is where I use them especially when using JavaScript or PHP to generate IDs on the fly to use with jQuery. Then again, I grew up on procedural coding and became an OO architect in the 90s with Java, C++, and ObjectiveC before I started working on HTML/CSS. I treat IDs as dynamic HTML instances and with CSS being declarative–and on that basis (well, okay, because it’s good OO practice too)–it makes littles sense for me to use them.

  • Michael J. Ryan

    I tend to mix them up a bit… my latest project is .less based (bootstrap) and I am using an MVC pattern for the server-side portion.. my main template puts an ID in the html tag of “controllername-actionname” or “public-viewname” (for public pages using the template). This way I can target a single page’s specific needs with an outer wrapper of #account-login { … } for example… I also add a “controller-controllername” class to the html. So that I can target a section of pages easily. Outside of this, most of my ID’s are more for JS than for CSS usage.

  • Thomas

    Lots of classes:
    Introduce bloat to your markup and blur the division between style and content. (i.e. )

    Lots of ids:
    Iintroduce bloat to your CSS, because you have to repeat rules on different elements and create weighted rules to override styles.

    My suggestion:

    1. Use the cascade properly
    2. Find the right mixture between ids and classes in order to keep your markup *and* CSS lean and maintainable

    It’s about balance and knowing what you do.

    While I agree, that reusable code is beneficial, it’s a bit far-fetched here. CSS is mostly about creating something unique: a style for a certain webpage. I don’t want to reuse *every* bit of a design, which I specifically created for this project, across different projects. That’s the type of bloat grid systems introduce, which provide lots of classes you end up not using.
    Of course it is good practice to use classes more often than ids, because you want to have certain styles repeated on various elements of the page.
    But specificity has a clear advantage: you don’t have to care wether changing the style of an id breaks your layout. When I want to change one element, but its styles are composed of 3-5 different classes, I’m in trouble. Changes are going to affect the design everywhere.

    And btw, I can still use classes on an id. They’re not mutually exclusive.

    @Andreas “Stop fighting against what’s very accepted by the most of the Front End community” – that’s a very funny thing to say :)

  • Erik Reppen

    This is terrible advice. Anybody who has worked with teams of 5 or larger has seen CSS that looks like this.

    .main-content .side-bar > ul > li { /*properties*/}

    That’s what’s a pain to override, not:

    #side-bar li

    The important detail is that you only use IDs to override more general styles specific to things that are only inside the ID element. Then you can go crazy with classes and tag selectors at higher node levels and never worry about breakage of those critical property overrides.

    Good CSS is minimal CSS Using IDs well leads to less CSS. Not using them at all as a hard and fast rule means you’re not doing it right. Start with general. Gather commonly re-used sets of properties into classes. And then sparingly, use IDs to override only the properties need to change in an ancestor element context.

    ID on the body? Idiocy. Always, unless you’re already cooked because of a CSS arms race that happened before you got there. But classes-only just means a higher quantity of classes which is a specificity mess that you can only clean up with even more classes if you never use IDs.

  • Bill Freese

    IDs can be used as anchors. Classes cannot. This is the actual functional distinction. So why do so many pages discussing ID vs class fail (like this very page) to mention that fact?

    • Dave Gregory

      Sorry, but this article is NOT about named anchors. (which is what you are referring to) No named anchors have been harmed in the making of this article. :)

  • Brian

    Great discussion! I too have been reducing the number of IDs in my CSS. IDs are great JS hooks and useful for named anchors so they are still present in my markup. Newer HTML5 semantic elements (header, footer, aside etc) used in conjunction with ARIA roles (banner, contentinfo, main, etc) and CSS attribute selector [att="val"] (particularly those that match substrings such as ^,$,*) the can greatly reduce or eliminate styling IDs while remaining clear (at least to me). I also have started using LESS and creating many separate files and using a master file to import the *.less files. Simply looking at the file system I know narrow down what styles to edit! It takes practice and I understand why many would object (verb) and keep the CSS “simple”, but for now for me it is interesting. Regardless, iIt is essential to constantly be learning and striving for improvement in this field!

  • dnut

    Ah…

    Many a person commenting on this article (which I am in total agreement with) seem to never have worked in an enterprise setting that does web development or may be were on the wrong side of that setting…

    All those ideas of using IDs for a header or a login box. How nice. Unfortunately, in many cases you develop your CSS code as part of some product. That product then leaves the R&D department and is maintained for a relatively long period of time. The developers who use the product to extend and adopt to their needs **can’t** just go and change that damn header when they need to change the color of the links in the new design. The have to work on top of it. Which they can’t. Because of IDs specificity.They can’t even hack it properly without killing any maintainability for the future. **!important** all FTW.

    People don’t seem to get it. Have you ever tried styling/re-styling CSS from one of the frameworks (Sencha, JQM, JQUI). They don’t use IDs. And even then, without extreme specificity issues, it is extremely not-easy to do.

    P.S. The comment on the named anchors just killed me.

  • Heloisa

    Though I’m fond of working with classes and I really like the OOCSS concept, I don’t think using classes or IDs is a single matter of “this is good”, “this is bad”. They both have their purposes. Classes are great for creating generic styles that will be reused along the project. IDs are needed to treat exceptions and/or unique styles.The secret is to use both wisely.

  • Mr.Key

    Well how many of you have a CSS “library” at hand which they deploy on each site ? I would say that CSS is actually very specific per page. Let’s say you need columns with width of 40px, would you need that columns size on every page? Heck no..

    Yes of course there are common thigs, which can be abstracted, it is a good idea to do it. A good examples are HTML component frameworks which provide themes (like JQueryUI, PrimeFaces, etc. etc.) If you write something like that it is absurd to use IDs…

    But then again, a CSS is created per page, meaning that CSS itself is quite specific to the layout of the particular page. Yes … you could abstract the base with which help you can create anything.. and this abstracted base is CSS, not classes in some major CSS library which are supposed to do every possible thing….

    After all is said and done I would suggest that using ID’s for particular page layout is OK, it even helps the semantic of the page and the CSS in a way and using classes when you write general-purpose library (again consider JQueryUI) then classes are a must.

    Very good article, and interesting follow-up in the comments. As always truth is somewhere between the two extremes.

  • Adrian

    I am a hardcore ID guy and understand the differences. This article makes sense from two perspectives. 1/ speed. 2/ ensuring that your code is not overly specific.

    My problem is that when I go to someone else’s code and need to make a change, if it is a class, then I can’t. I don’t know where else may get screwed up. If it’s an ID, then I’m safe. This is called readability. That being said, my ID use over the past week have certainly reduced drastically.

  • RR

    First of all: I’m dutch, so I’m not your English grammar or spelling fairy.

    I read the whole article, also most of the comments and I do understand both sides of the story. In fact: I’ve BEEN on both sides of this story. I experimented with this years ago, writing with lots of id’s and few classes or the other way around. My conclusion is that only using classes is not smart at all. You SHOULD go mixed mode with this for the sake of structure!

    I’ve been writing in many different languages for over more than a decade now, and I kinda use the same type of structure in all languages. Just to be a bit more detailed, I write in HTML4/5, CSS 2/3, JS/jQuery, JSON, PHP, (My)SQL, XML, HTA, BATCH, AS and many more, and structure is what is most important!

    So, to respond on this article and give some common sense feedback:

    - Specificity: Just using classes is not smart at all because there are other languages that DEPEND on being specific on your target or selector. Specificity, when used the right (smart) way will also give you a better code structure, this way future devs can pick up where you stopped because your code is READABLE. There are still a lot of devs that underestimate this and don’t use indentations or parent / child like programming: They should stop creating this pollution and apply for another job.

    - Speed improvements: Can be neglected both ways for a large part. Nowadays we have fast internet, fast computers, tablets, smartphones, netbooks, etc. I also don’t believe in minifying for the sake of a few nanoseconds. These measurements are always being taken out of proportion and people start causing a panic for nothing. Of course there is a difference between writing junk and writing clean code, like: “duh…!?” (imagine a blond trailer park chick working at the local road cafe chewing gum while saying that and rolling her eyes……….stop staring at her boobs!)

    - Use comments in your code: Do I really need to explain this…?

    - ID and Class names: THINK first before writing your code and make some on paper concepts so you have a guideline! This way you won’t jump into a name giving death match to self destruction. Have a plan, never dive into a pool of sharks, or crocodiles, or piranhas, or mothers in law in their old bathing suites revealing their cellulite skin.

    Ok, so just to keep it even more short than I am doing already:

    - Just applying this “re-usable” way of CSS makes it to dynamic, and we all know what happens with code that’s written like this and it’s being changed: Avalanche!

    - Have a plan, minimize name similarity in your code!

    - Use parent / child like code for the sake of structure! Use comments and indentation the readable way!

    - Think about other devs when writing your code, don’t be a smart*ss!

    And remember, there is not 1 way that will be THE way to do things… I personally don’t need to proof anything to anyone here in this article. This is just my personal experience in being a dev in more than 1 language for over more than a decade. I’ve worked on websites, built crm, cms, dms, ems, all that stuff…

    That being said: GODSPEED!