When using IDs can be a pain in the class…

There have been a few articles flying about lately which tell you never to use IDs in CSS selectors. I always get a little concerned when articles like this command rather than advise, they often neglect to take into account context and necessity. I’m going to try and offer up one decent reason here as to why IDs might trip you up unnecessarily (and how you can avoid the pitfalls).

Since authoring this article I have decided that a blanket ban is sensible. Save yourself many potential headaches and never use IDs in your CSS files.


ID selectors are fine, valid and perfect for styling unique parts of pages. They’re HTML/CSS basics, you can use one ID per page and style the relevant element with #the-id-you-chose.

IDs, as well as being non-reusable, carry quite a high specificity, take the following:

<p id="intro" class="excerpt">Lorem</p>

#intro{ color:blue; }
.excerpt{ color:green }
p{ color:red; }

Even though we define #intro first—thus expecting it to be overwritten by subsequent matching selectors—it still takes precedence over any other rules. This is the IDs heightened specificity, and this is where you can come unstuck…

Reusability

One argument against using IDs is that they can’t be reused, but to my mind this is a weak argument. The whole point of using an ID is that it’s unique; if you want to reuse something you’d use a class. Developers know this, developers aren’t stupid so to tell them not to use an ID because it’s not reusable is, in my opinion, quite patronising.

Also, some things just can’t be reused. Some designs would be wholly impossible to have, say, two content areas in. You couldn’t reuse that even if you wanted to.

Wild card

That is wild card meaning a person or thing whose influence is unpredictable or whose qualities are uncertain and not to be confused with the CSS wildcard selector (*{}).

One of the main and, in my opinion, most valid arguments against using IDs is that they can introduce specificity headaches where you want them least, and it can be a total nightmare fighting your way back out.

Using an ID in a selector instantly adds a specificity wild card (note, not wildcard), and you might not want this effect. It is, in a way, similar to !important; it is a trump card that will override nigh on all other types of selector. You probably don’t always want this.

The best way to illustrate this is with a specific example.

Let’s imagine you’re building a site and one of the requirements is to have a reusable Twitter widget that needs to be placable wherever the client chooses. Let’s for example say they want to kick things off with having the widget in the header and also in-page, at the bottom of an article. The Twitter widget’s styling must remain consistent.

So, let’s look at some example code.

Here we can see that we have a small specificity problem, the #header a rule has a lot higher specificity than .tweet a and therefore the links in the widget adopt the header’s (unreadable) colour. Remember that the Twitter widget’s styling must always remain the same so this is not ideal whatsoever.

We can work around this by adding a new selector to the .tweet a rule Or, even worse, we could add an !important to the relevant declaration. Shudder…

Now, you don’t need me to tell you that this is far from a nice solution, as soon as that widget gets put in the #footer we may well have to add yet another selector, which will prove a maintainability nightmare. This is not a very future-proof fix.

This is where using IDs can be a pain for you, where a specificity trump is introduced.

A better fix: add a class instead of (or as well as) the ID on that header div, thus: http://jsfiddle.net/csswizardry/gTZGq/3/

That now brings the specificity gap way down to, well, zero. Removing the ID means that you now don’t have to fight yourself out of a self-induced specificity war.

I did mention that you can add a class as well as the ID or remove the ID completely. It depends…

Remove IDs completely?

We’ve covered where IDs can trip us up and be but they serve a purpose other than style-hooks; they can be used as fragment identifiers for marking landmarks in the page.

I’m sure you’ve seen ‘Skip to navigation’ or ‘Jump to content’ links in pages, and these wouldn’t work without our IDs so we need to keep those in as well as adding our new class.

So, as is the case with most development conundrums, it’s all about context. You know your context better than I, or anyone else does, so don’t let anyone else tell you what to do. If you want to keep an ID for completeness or for fragment identifiers then do, it’s totally your call.

Final word

So yeah, IDs aren’t evil, they’re perfectly valid and a blanket ban on them is stupid. Use your own knowledge and context of the project to use the most suitable and sensible solution.

Don’t stop using IDs, just be aware of where they can cause you headaches and know where to sensibly circumvent them. Anyone telling you not to use them at all is not wrong, but they’re definitely not right…

By Harry Roberts on Sunday, September 11th, 2011 in Web Development. Tags: , | 28 Comments »

+

28 Responses to ‘When using IDs can be a pain in the class…’


  1. Steve Rydz said on 11 September, 2011 at 9:26 pm

    Thank you for writing an article that actually gives some insight into why we should sometimes use classes instead of ids.


  2. Jitendra Vyas said on 12 September, 2011 at 2:42 am

    Good points I was also thinking upon should I use ID or not after CSSLint Tool but I think. You have mentioned some good points.

    I’m using id mainly for sections like header, footer, wrapper, Logo, sidebar etc. and I never faced any difficulty. and as you mentioed ID is also require to make Back to top links.

    Great Article.


  3. Gavin Dellbridge said on 12 September, 2011 at 12:09 pm

    Good stuff, I completely agree and as said before it’s good to have some rationale rather than sweeping statements.

    This “don’t use ids” campaign reminds me of “don’t use tables”. Without a real explanation you get people who will blindly follow and built whole sites without tables (even the tabular bits) because tables / ids are ‘bad’.


  4. Anton said on 12 September, 2011 at 5:12 pm

    I like to use ID-s when necessary – in Javascript for example.


  5. Greg said on 12 September, 2011 at 8:43 pm

    As Anton mentions, IDs are super-helpful for all kinds of JavaScript.

    But let’s forget that for a moment and think about pure CSS/HTML (this is CSS Wizardry after all!). The pitfall of IDs is specificity, but its main benefit is… specificity!

    Like any tool, as long as you know how to use it properly (and I agree that it’s patronizing to assume we don’t!) the higher specificity can be a real asset.

    And because I like to blather…

    I couldn’t agree more that it’s not the advice that’s the problem, it’s the tone of commandment. My fur went straight up when the language of CSS Lint presented this piece of advice as a rule when even as a so-called “best practice” it is debatable.


  6. Louis said on 12 September, 2011 at 8:58 pm

    Harry, can you cite a source that says “never use IDs”, and that doesn’t qualify the statement? I don’t think any of the (at least reputable) sources have said not to use IDs ever. The ones I’ve read certainly point out the possibility of using IDs for fragment identifiers and for scripting hooks.

    For example, the CSS Lint about page says: “Don’t use IDs in selectors”. That’s a reference to your stylesheet, the selectors you create. Not a reference to IDs in the actual HTML.

    So what you’ve done here in this article is show some practical reasons why IDs should basically not be used, which is good, and I think you’ve done a great job of showing why IDs in selectors can be troublesom. I just think the argument you’re putting forth is a bit of a strawman argument, since nobody is really saying “never” use IDs. But maybe I’m wrong.


  7. Keyamoon said on 12 September, 2011 at 9:06 pm

    IDs are almost always against the DRY (don’t repeat yourself) principle. For styling, you can always used classes which make your code much more reusable. I personally have stopped using IDs and I believe using IDs is a lazy bad practice, but yea still “valid”. I only use IDs when it comes to javascript. In my last work, a full featured Wordpress theme, I only used one ID for styling! whenever you feel the urge to use an ID, just sit back and start thinking on how you could define some reusable classes that can together, make the unique styling that you are planning. It works, it’s harder but it works. And you will be rewarded later on.


  8. Harry Roberts said on 12 September, 2011 at 9:06 pm

    @Loius: This is splitting hairs now, but most articles say not to use IDs in CSS selectors, yes.

    I say that There have been a few articles flying about lately which tell you never to use IDs in CSS selectors, we have articles entitled:

    I am saying that isn’t necessarily right and am showing only one circumstance where I believe they might give you problems.

    The ‘other’ articles are talking about (not) using IDs in your CSS, so am I.

    H


  9. Louis said on 12 September, 2011 at 10:08 pm

    @Harry:

    In your conclusion you said:

    “So yeah, IDs aren’t evil, they’re perfectly valid and a blanket ban on them is stupid.”

    My point is that nobody has placed a ‘blanket ban’ on IDs, only for CSS styling.

    The reusability argument is valid, because whatever you can do with “#content” you can also do with “.content”, so why use an ID? Also, there will naturally be instances where certain whole sections will not be reused (like the “content areas” you mentioned), but with OOCSS, the point is to abstract certain styles out of that “content area” and only use “.content” for unique styles. So, it’s not about abstracting entire widgets or sections, it’s about abstracting patterns (or characteristics?) out of those sections.

    So I think it’s good advice: Never use IDs in CSS selectors.

    Of course, if you look at my work, I’ve used IDs over and over for CSS styling, so I’m just starting to implement this advice. :)


  10. Henrique Erzinger said on 12 September, 2011 at 10:41 pm

    @Louis:

    When he says ‘blanket ban’, he is talking about css selectors. That’s obvious, since it’s the hole point in the article. All that was said here was about styling. Period.

    If it’s a good advice or not is something debatable. I particularly don’t think so, because of the word “never”. The context should define when it is or isn’t good to have the mentioned specificity in your selector.

    The reusability argument is stupid not because it’s false, but because it’s OBVIOUS. If someone doesn’t know that, well he’s in the wrong market. It’s so basic it doesn’t deserve the status of a valid argument.


  11. Gary said on 12 September, 2011 at 11:52 pm

    This article is just as patronising as any other article. You’re assuming the same as the articles you reference in that you’re suggesting developers haven’t already made a conscious decision regarding the specificity.

    Using #header a { color: #FFF } means the developer has made a clear decision that ALL links in the header should be white. Furthermore, should one decide that the .tweet link in the header should be a different be colour to all other header links then there is no issue in being more specific and prefixing the .tweet a definition with #header.

    Replacing ids with classes is only throwing a lifeline to those who don’t understand specificity or think about the rules they’re writing.


  12. Harry Roberts said on 13 September, 2011 at 7:58 am

    @Louis: My whole article is in the context of CSS selectors, though. That’s why I opened with that context, so the reader knows that everything that follows is in relation to selectors.

    ‘Blanket ban’ could have been ‘blanket ban on IDs in CSS selectors’ but that’s far too verbose when then article itself is dealing with selectors.

    I think we’re wasting time arguing a moot point here…


  13. Harry Roberts said on 13 September, 2011 at 8:14 am

    @Gary:

    “there is no issue in being more specific and prefixing the .tweet a definition with #header. “

    Yes there is, this is not a maintainable solution.

    The problem was caused by an overly specific ID, thus we remove the ID and use a class to bring the specificity down: we don’t actually need or want the header or the widget to have a higher specificity than the other, but using an ID causes this.

    Our ID is being a pain in the ass and it’s not necessary.


  14. John said on 13 September, 2011 at 8:46 am

    Great insight and good advice!

    You should maybe use classes instead of id’s in some of the other examples and fiddles you provide on your blog – you know, be consistent, and like “practice what you preach” ;-) (or is there a reason for using id’s in examples?)


  15. Harry Roberts said on 13 September, 2011 at 9:21 am

    @John:

    The reason I use IDs in examples (and will continue to) is that I rarely run into any specificity issues. I’m not advocating using classes as standard, just when you find you might be getting yourself tangled up. Luckily demos tend to be small enough for this not to happen.

    H


  16. Alex said on 13 September, 2011 at 12:43 pm

    Thanks, was great to find this article written in clear understandable language for a non-developer like me. Just what I needed.

    cheers
    Alex


  17. Louis said on 14 September, 2011 at 5:00 am

    @Harry:

    In the first paragraph you said:

    “I always get a little concerned when articles like this command rather than advise, they often neglect to take into account context and necessity.”

    There is no “context” that would necessitate the use of an ID over a class for CSS styling. So, the “command” is a valid one.

    All you have to do is give me just one example where an ID is more beneficial than a class, and I’ll agree that the command is wrong. But, if you can’t do that, then the command stands as valid: Don’t use IDs for styling.

    The *only* argument that is in favour of an ID over a class is the small and almost irrelevant performance benefit to using an ID over a class. But, when the drawbacks are considered (specificity and re-usability) then that completely negates that benefit, so the “command” becomes a valid one.

    And hey, nothing personal here. I just like to debate. :) And I’m just throwing out some opinions on OOCSS, because it’s something I’m taking more of an interest in. So thanks for starting this discussion, it’s a good one.


  18. Harry Roberts said on 14 September, 2011 at 7:36 am

    @Louis:

    Riiiight. Well I can think of:

    Comfort; a developer is used to IDs and it makes it easier for them (this is a weak argument, I’ll admit).

    Speed; as you say, also weak.

    Specificity; When you do need a specificity trump without using !important or a convoluted selector.

    Necessity; If a developer is not using OO then the likelihood of needing the re-usability of a class is negotiable.

    Not using IDs is sensible but it also relies on a lot more as well. This is why I say that a blanket ban is daft because there’s a lot more context around it IMO.

    If a developer still wants to use IDs then who are you, I or anyone else to tell them they can’t? We can advise and teach the drawbacks but at the end of the day it’s up to that developer to do what they want with it…


  19. Jeremy Nicoll said on 17 September, 2011 at 8:00 pm

    There’s one thing that the article trips up on, though: ID’s don’t trump everything. There’s a system that assigns a certain number of points and whatever has the highest number of points is what gets chosen.

    http://css-tricks.com/855-specifics-on-css-specificity/


  20. Harry Roberts said on 18 September, 2011 at 2:29 am

    @Jeremy Nicoll: Don’t worry, I understand specificity…


  21. Mike said on 20 September, 2011 at 9:30 am

    I rarely use IDs for styling (rather for javascript), and if I do it’s almost entirely for elements without children, like for example:

    .footer #copyright-text

    This way I get none of the drawbacks described here.


  22. Marc Haunschild said on 21 September, 2011 at 10:24 am

    Thanks for this article – but even in your worst case example the problem with the higher specificity is easy to avoid.
    A simple #header>p>a will do the job. In 15 years of web developing I can not remember a single combination of classes and IDs, that I could not solve with such a simple code.
    Also this problem very often does not even appear, when you give general colors for links and add another rule only for links, that should get a “special” color.
    Some may say, that this is slower – yes it is – so what? You won’t need this a hundred times on every page and no real person (no matter how old or how slow his computer works) will feel the difference!


  23. Marc Haunschild said on 21 September, 2011 at 10:29 am

    @Harry Commands are good for people that do not want to think of their own – developers should think, I guess. :-)
    And I very much like using IDs to make clear, which parts of a site or page or unique. This is part of my concept. Trying to avoid these decisions means, that someone does not have a concept.


  24. Greg said on 25 September, 2011 at 5:37 pm

    You can always use ‘only classes’ if you are willing to admit that it’s just semantics. In other words, there are times that you have opted for uniqueness in your selectors, and whether you use an ID or a unique class, you have just that– a single instance of that selector. It’s really splitting hairs to say it can be done with classes. It can, but I wouldn’t.

    Since the instance is unique to the page (there can be only one) I would actually argue that it’s semantically confusing to use a class (even though you CAN!) because classes (in general) to me imply reusability. Unique classes shouldn’t be reused.

    And to restate it yet again, just because you ‘can’ use classes in every situation in which you could use IDs, doesn’t mean you should.

    So, I have a site that has 4 distinct product lines. Think something like Office or Adobe Creative suite– each of those products carries with it a unique color palette (everyone knows the blue of PhotoShop and the orange-yellow of Illustrator). So I’ve decided that I want my links and titles in each of these sections to reflect that particular product’s colour palette. The easiest way to accomplish this is to add a unique identifier to my body tag or a wrapper tag of some variety, designating my product.

    #superProduct a, #superProduct h1 { color: red; }

    and

    #fantasticProduct a, #fantasticProduct h1 {color: blue;}

    This ensures that the default link font colours for my two products are different.

    This can be accomplished in the exact same manner using classes! Instead of #superProduct I now have .superProduct. It doesn’t matter– with the performance difference being negligible at best, I really don’t care. So yes, it CAN be done and without even changing my design.

    But there’s only ONE instance of this class on the page. According to the way I’ve designed the site, there can only EVER be one instance of #/.superProduct on the page. So guess what I prefer using? IDs all the way. It’s a semantic indicator that this selector will appear only once.

    In other words, styling using a class has no practical difference here. That being the case, I prefer to use an ID, for code aesthetic as well as organizational reasons. I freely admit that the ID isn’t necessary, but to be told I’m doing something “wrong” because I prefer it is ludicrous.

    Along that line:

    Now, let’s assume that within a fantasticProduct page, I want to make a quick reference to superProduct. Because I don’t want to remember specialized names, I decide to do this:

    #superProduct a, .superProduct { color: red }

    Now, inside of my fantasticProduct a fantasticProduct page, I can do this: <a href=”#” class=”superProduct”>check out superProduct!</a>.

    Could this be done with classes? Of course!

    .superProduct a, .superProductLink { color: red; }

    And then my anchor tag would have the class “superProductLink” instead, and everything would work perfectly fine.

    But I don’t prefer it that way. I prefer using the same productName for the ID and for the class. Then when I use a productName class I know that I’m intentionally deviating from the page default.

    The main takeaway is that everything in the above method is possible because of the uniqueness of the selector (on the body or wrapper class). I would NOT want to just have just the “fantasticProduct” class that gets added to the headers and anchors for each instance. It’s certainly reusable to do it that way, but it’s not efficient in terms of writing the markup.

    So once again, it’s not because you “must” use an ID. As Harry correctly states, you can solve any styling problem using classes instead of IDs. But why would you? It’s just as silly to force the use of classes when they’re just “fake IDs” as it is to be overly granular.


  25. Peter Butler said on 14 November, 2011 at 2:27 pm

    Hey Harry, nice article man! This problem has given me a few headaches in the past, based on what you say I think it’s best to only use IDs where completely necessary and for everything else use classes.

    If you built a website in HTML5, could make use of the new syntax like: header, footer, article, aside etc without the annoying specificity that ids generate? Or would they apply to those top level tags too?

    One tip I’d recommend if you really can’t get around using an ID is, when it comes to finding the style path, if you use Firefox and Firebug you can right click and inspect element then right click on the style in the firebug pane and Copy CSS Path. From there paste it into your CSS and just delete it up to the last ID tag.

    Enjoying reading your blogs posts :)

    http://www.twitter.com/midgar777
    http://www.thecityisburning.com


  26. Jason said on 9 March, 2012 at 4:00 pm

    This should be required reading for EVERY CSS designer!


  27. Fred said on 13 March, 2012 at 2:01 pm

    I was sceptical when reading your github post on dropping ID’s, but this does make sense. Good advice that I hadn’t thought of before, will consider using for future projects.

    Cheers.


  28. AntoxaGray said on 3 August, 2012 at 12:03 pm

    Recently I changed my mind and stopped using ID for styling.

    Now I can write class=”foo bar” instead of id=”foo” class=”bar”, also it helped me in making css more object-oriented, reducing time to code.

    I never thought about ID priority over class however, now I see another reason not to use ID in css.

    There is one exception, though. I use #js id if I need fallback for disabled javascript (I’m not sure if I ever need to use that: who in this world surf the internet with disabled js anyway?).


Leave a Reply

Respond to When using IDs can be a pain in the class…

Hi there, I am Harry Roberts. I am a 21 year old web developer from the UK. I Tweet and write about web standards, typography, best practices and everything in between. You should browse and search my archives and follow me on Twitter, 7,791 people do.

via Ad Packs