In Defense of Descendant Selectors and ID Elements

Except when I occasionally update Designing With Web Standards, I quit writing hands-on, nuts-and-bolts stuff about CSS and HTML years ago. Publishing abhors a vacuum: other designers and developers took my place. For the most part, this has been a good thing—for them and for our industry. The best writers about code have always been those who spend 25 hours of every day up their necks in it, as I used to. While folks like me migrate into strategic or supervisory roles (providing us with new places to innovate and new things to write about), a new generation of code crafters is making new discoveries and sharing new teachings. Ah, the magical circle of life.

But amid the oodles of resulting goodness, I find occasional stinkers. Take the notion, now concretizing into dogma, that id should almost never be used because it has “too much specificity,” and that class names are always preferable. Respectfully, I call bunk.

To my knowledge, this notion comes out of Nicole Sullivan’s brilliant Object Oriented CSS, an approach for writing HTML and CSS that is designed to scale on sites containing thousands of pages, created by dozens of front-end developers over a period of years, generally with no rules or style guide in place (at least no rules or style guide until it is too late). On sites like these—sites like Amazon or Facebook that are hosed from the get-go thanks to too many cooks and no master chef—the use of structural id and descendant selectors can be problematic, especially when inept coders try to overwrite an id-based descendant selector rule by creating ever-more-specific descendant selector rules.

In this particular (and rare) circumstance, where dueling developers have added rule after rule to a huge, shapeless style sheet that is more of an archeological artifact than a reasonable example of modern code, Nicole’s admonition to avoid descendant selectors based on id is probably wise. If you have the misfortune to work on a huge, poorly developed site where you will never have permission to refactor the templates and CSS according to common sense and best practices, you may have to rely on class names and avoid descendant selectors and ids.

But under almost any other circumstance, properly used ids with descendant selectors are preferable because more semantic and lighter in bandwidth.

The way I have always advocated using id, it was simply a predecessor to the new elements in HTML5. In 2000, we wrote div id="footer" because we had no footer element, and we wanted to give structural meaning to content that appeared within that div. Today, depending on the browsers and devices people use to access our site, we may well have the option to use the HTML5 footer element instead. But if we can’t use the HTML5 element, there is nothing wrong with using the id.

As for descendant selectors, in a site not designed by 100 monkeys, it is safe to assume that elements within an id’d div or HTML5 element will be visually styled in ways that are compatible, and that those same elements may be styled differently within a differently id’d div or HTML5 element. For instance, paragraphs or list items within a footer may be styled differently than paragraphs or list items within an aside. Paragraphs within a footer will be styled similarly to one another; the same goes for paragraphs within an aside. This is what id (or HTML5 element) and descendant selectors were made for. Giving every paragraph element in the sidebar a classname is not only a needless waste of bandwidth, it’s also bad form.

Say it with me: There is nothing wrong with id when it is used appropriately (semantically, structurally, sparingly). There is plenty wrong with the notion that class is always preferable to descendant selectors and semantic, structural ids.

Please understand: I’m not disparaging my friend Nicole Sullivan’s Object Oriented CSS as an approach to otherwise unmanageable websites. No more would I disparage a steam shovel for cleaning up a disaster site. I just wouldn’t use it to clean my room.

I’ll be discussing code and all kinds of other things webbish with Chris Coyier and Dave Rupert on the Shoptalk podcast today. Meanwhile, let me know what you think. And don’t forget November 30th is the sixth international celebration of Blue Beanie Day in support of web standards. Wherever you may stand on the great id debate, please stand with me and thousands of others this November 30th.

60 thoughts on “In Defense of Descendant Selectors and ID Elements”

  1. Interestingly enough, I got all bent out of shape when I heard Nicole speak on the topic at AEA a few years ago. After cooling off and talking about it with a few other friends, I came to realize that had I missed the caveat to Nicole’s approach that you mention here. Sticking with classes on large sites with many developers is a no-brainer, but I was doing 99% of the coding on 99% of the sites I was working on, and her approach seemed overbearing. Sensibility is the key. Thanks for putting into words what I’ve been thinking about the topic.

  2. I totally agree that the object-oriented CSS approach is too heavy-handed for most development. For large applications (see: Facebook) it’s the only way to maintain sanity, but for smaller projects (IMHO) it’s overkill that adds too much abstractness.

    That said, there are other reasons to use classes over IDs. The first, as Russell mentioned, is re-usability. If I want, for example, an arbitrary number of image slideshows on a page, I can’t use IDs to style them.

    Another reason is rendering performance. While it’s true that an ID selector is the fastest to render, as soon as you add a descendant you lose that performance benefit, and then some.

    (Here’s a great post about CSS selector performance by Oli Studholme: http://oli.jp/2011/ids/)

    The third reason I prefer not to use ID selectors is that I really enjoy the clarity that the approach gives my development. For the most part I use IDs for javascript purposes, and classes for CSS purposes. If an ID is used by both my CSS and my JS, I need to change both if the ID changes.

    I still have to use classes for jQuery purposes at times (I try to use data attributes instead, when it makes sense), but for the most part I’m able to keep that separation intact, which makes my life easier.

  3. The discussion around these points is based on Modular and Scalable code, so where as you can indeed write your code quite specific, its not going to help you in larger projects and teams.

    If your working on your own then by all means you can do what you want, however working on larger projects, open source, and in teams these issues DO matter.

    What I take away from all this is spotting patterns, reusable layout and style, abstracting that to a reusable blocks of code. Styles in your footer may appear in the sidebar at some point, to extend your point.

    They’ll always be more specific rules to apply but since these can be applied with classnames also I just don’t see, given the pain introducing ID’s into your CSS can cause, what the benefits are.

    Yes they’ll be minor exceptions, yes you can’t control an inherited codebase, but if you approach your builds with the mindset encouraged in Harrys articles and the like, then your code *will* be more modular and repeatable which more often than not is better.

  4. I forgot to mention: The performance benefits of one or the other are very slight. I think they become relevant in a Facebook-like environment, but for your average site they are so slight as to be irrelevant. So, it’s probably not worth jumping through hoops to avoid ID selectors just for performance reasons, but there are other reasons to take a look at the approach.

  5. I was wondering if you were ever going to say something about this trend. Why put a class on a paragraph in the footer when I can just say footer > p? Yes, reusable classes are great for widgets that get reused, and yes on overuse of ID selectors causes problems (I’ve run into it on sites I’ve created) — it’s a balance of the two. Something you taught us years ago with DWWS.

  6. I agree with Tim. I think you never know where a site is going to go and how it is going to change in the future and what code you may need to reuse. You also don’t know how a team will grow and who will be working on it. So instead of setting things up to be more specific by using ID, start with classes so that when things go forward you have more flexibility. I write this having worked on an insurance company web site that ended up having a string of contractors coming through the doors and so the styles got out of control. This is because no one was in charge, but also because things were written very inflexibly at the beginning. If you start out flexible and less specific, you are set up for more success as you move forward.

    I do agree that a lot of sites don’t need to follow all the rules, but for any large corporate site, it is a better way to start out so you aren’t shooting yourself in the foot as your site grows.

  7. Responsive design is very difficult without the use of IDs, or the assumption that certain classes shouldn’t be used more than once, or you lose the ability to target specific parts of the page for resizing/reorganizing content.

    My preference is to move OOCSS concept into SASS/LESS mixins and apply those mixins to elements with more content-appropriate ids.

    At one size, this might be appropriate:
    #category-menu {
    @include vertical-menu();
    }

    But at a smaller size:
    #category-menu {
    @include off-screen-menu(‘left’);
    }

    Flexibility without sacrificing OOCSS principles.

  8. Thankfully I never heard of that idiotic “rule”.

    My own rules have served me well for the past 15 years.
    I use IDs where there’s supposed to be only one element of that kind on a page that has a special meaning, like id=”logo” or id=”footer” or “header” or “primary-menu”. I use descendants for elements inside ID to define their default properties. I use classes to change the default behavior based on context and where there are more elements of a kind, like class=”article” or “selected” or “warning”.

    This method has served me well for small projects and large ones.

    I also don’t buy the “large team” thing. In software development, all smart companies have coding standards. I worked on projects with 50+ devs, with a style guide everyone’s code was conforming to a set of rules (not just aesthetic but functional as well) and there were no issues.

  9. You’re right, Jeffery: On a small site with few developers, or one that wont change very often, following the tenets of OOCSS is pedantic.

    However, as a developer working on a site with at least 100 monkeys spread over multiple in-house teams and external agencies, OOCSS is a godsend. When you look through a site’s CSS and see the same button defined a dozen times, you know a better approach is needed. A styleguide built with modularity & reusability in mind is the only way to stay sane on large-scale sites; there’s just no other way to ensure visual consistency.

  10. Isn’t the HTML5 footer element more like a class, in that it can appear more than once on the same page.
    Jeremy Keith suggested using ARIA roles to replace IDs I think, so instead of #footer, use footer role=”contentinfo”, etc…

  11. Jeffrey,

    Would I be mistaken thinking that the point of your message here is about not getting too dogmatic about any particular way to define “best practices”?

    What I heard in your message is that you grasp what is good and right about the modular approach, but don’t feel the need to ditch IDs just because of it.

    I am a big, big fan of OOCSS/SMACSS (whatever the kids are calling it these days) – but feel like the “dogma” that arises from these sounds principles swings the pendulum too far from a balanced approach. The same thing happened in the “Zen Garden” approach, where we left the HTML alone and did crazy selector things to make the CSS happen. Either extreme can spell problems, IMO.

    Mind you, I don’t think OOCSS/SMACSS themselves are dogmatic. I think how those principles are interpreted can breed dogma. So, I’m not disparaging these approaches at all. I use them and find great value in them.

    Just wondering: did I hear you correctly? Modular CSS is good. Just stay balanced and use what you need. Scoping with IDs can be an additional tool. Why knock it?

  12. I’ve never really bought into any of the OOCSS, BEM, SMACSS methodology, as I think that every project is unique, with its own set of standards that needs to be established at the beginning of the project. I do however appreciate and agree with everything they set forth in those standards for beginners to CSS architecture.

    That being said, the main reason I don’t use ids, descendent selectors and anything else that tightly couples my HTML to my CSS, is forward or progressive thinking. When we didn’t have the tag, we did use ; and we style according to the #footer {} declaration. Then we started styling to footer {} with just the element as a selector; what happens when we get a new tag or we decide there is a better way to mark up our HTML? We can’t just go in and change our HTML without breaking our layout and everything associated with it. The ideas that were set forth by you were to always separate out the layers of development. My HTML should not be tightly coupled to my CSS nor JS, and all the subsequent variations.

  13. The specificity argument is moot as #content > p is essentially the same number of specificity points as .content > p if you always use IDs or always use classes (that is overwriting a style with another style) ie. #parent #content > p or .parent .content > p

    Like others have said, the best thing about classes is re-usability. Even if you think something NEVER will appear twice on a page, a client will prove you wrong and make you duplicate something. Also, once you start using classes as opposed to one-off IDs it gets you thinking in the proper mindset of “what can I reuse form this?”

  14. I really wish the godfather of Web Standards would not refer to the practise of placing ID attributes on DIV elements as “semantic”.

    The DIV element, to quote the spec, has “no special meaning at all”. To imply that giving it a private name via the ID makes it somehow magically “semantic” (which, regarding semantic HTML, refers to computable/parsable meaning) is incredibly misleading.

    I shall not be “saying it with you”. Please explain yourself.

    P.S. @Paul: You are quite right. The HTML5 footer element is used to close sections. The document is a section so it can have a footer, but so are subsections within that document. This article refers implicitly to HTML < 5.

  15. “that id should almost never be used because it has “too much specificity,” and that class names are always preferable.”

    I also agree to disagree on above’s statement. I’m very strict on ID’s and classes. It helps me to get a quicker understanding of the layout (which elements are unique on a page and which are returning elements). We seperate elements with ID’s and classes to prevent markup conflicts… ‘Especially’ when multiple designers and coders are working on a CSS stylesheet.

  16. I’ve started using classes for everything now.
    .footer li, is the same as #footer li for me (even though .footer li scores 11 specificity points, and #footer li 101, in real terms they are generally the same if no IDs are used in the mark-up at all)

    Is the bandwidth saving purely that “id=” is fewer characters than “class=”? If that’s the case, when considering the number of fonts, transparent pngs, CSS animations and full screen pictures used on modern websites, surely – in a “let’s save bandwidth” case – we’re focusing on the arrangement of furniture in a room, whilst failing to notice the room is on fire!

    Does using an ID have any accessibility and SEO advantages?

    If not then ID just feels like a hangover from older thinking, when sites were more “set on stone” and less modular than they are now.

    When I weigh up the specificity advantage and possible subsequent (minor?) bandwidth saving of IDs, compared to when a client decides they want multiples of something which to begin with was to be one – and the mark-up, CSS and specificity head-ache that could bring, I feel using classes has a stronger day-to-day advantage than a relatively small victory in semantics.

    If I’m wrong on this, I’d welcome a rebuttal :)

  17. @Tim Murtaugh: +1000000000

    CSS is a horrible, twisted nest of a language. (Is it a language?) No matter how you use it, you’ll have problems. Choose which bag of problems you prefer for the practical long-term maintenance of your code base.

  18. If ID’s are used with caution (for structure only that really can’t be duplicated : you can only have one header in a page, even if it contains several banners), they are not a problem for not-so big projects.

    Furthermore, they can be VERY useful when you linearize a page for smartphone, for internal links. So please, do not kill IDs. :)

  19. I think its a case by case thing, and in most cases you could be right. I could set my css footer > p { style} . What if I have footers on all of my articles (semantically correct in HTML5)? I then have to go article > footer > p. or I can add 1 class. If my classes are modular I can reuse them across multiple selectors. This potentially reduces my css. For example a class of .heading-sub for sub headings is usable regardless of what element they are). Its one line in my stylesheet on one selector.

    There is also the issue regarding how selectors are parsed by the browser (right to left) so if I say footer > p my understanding is that the browsers finds all my p tags, then checks if they’re in the footer. This might be micro optimisation, and there are a whole bunch of things more important (gzip anybody?), but arguably so is the practice of reducing classes in your documents.

    The compromiseis to use a specific class on your footer instead of an id (eg. footer class=”post-footer”). This way you get the benefit of specific classes without the potential specificity issues of an ID. Mildly less semantic, but if I have to pick up your code one day, I’ll have a whole heap of love for you.

    Harry Roberts (@csswizardry) has a great post about this (and says it a lot better than I can):

    http://csswizardry.com/2012/10/a-classless-class-on-using-more-classes-in-your-html/
    and yesterday a nice related post:

    http://csswizardry.com/2012/11/code-smells-in-css/
    I think ultimately, its your code, do what you like. Some of the hatred in the comments above (not in the original post btw) is unnecessary. What ever floats your boat I guess kids.

  20. I agree that we should be thoughtful and balanced in our approach.

    For some time, I have been feeling uneasy with the class dogma. I have seen some crazy naming schemes. Naming is probably one on the hard aspects of web design, and because “every HTML element had to have a class attribute defined” it is easy to run out of meaningful yet readable names for classes.

    My personal rule is to use class names to facilitate modularity and reuse, and use IDs when specific exceptions are necessary. Why should I invent or leaf through a thesaurus for a new class name when I need to override one or two properties?

    I also think that setting more general properties on things like #footer > p is not a bad idea.

  21. I sometimes use IDs on to apply different properties on the same classes for different sections of the site. It is common for an to contain the same content type (usually they are lists of things,) which needs to be styled differently in another context. This could easily be done with classes, but I find IDs help me organise my stylesheet in a more readable way.

  22. Mr. Z, you took the words right out of my mouth… to the extent that I haven’t already been blabbing them all over O’Reilly titles that have my name on the cover.

    That said, my ideal publishing platform would have a hook for style element content on every page. That would, in my opinion, eliminate a lot of the need for id abuse.

    As for descendants… if you’re not going to use them, what’s the point?

  23. “Giving every paragraph element in the sidebar a classname is not only a needless waste of bandwidth, it’s also bad form.”

    I don’t think anyone is advocating this at all. OOCSS is all about recognising repeated design patterns. For your example, if you had “#footer > p” you wouldn’t replace that with “.specialstyle” applied to every paragraph, you would use “.specialstyle > p” and apply that class to the footer element (with a more semantic name, obviously).

    This “special style” you thought was unique to your footer? Turns out it wasn’t so unique after all, you want the same style in a new sidebar module. Shame you will need to continually update your selector with “#footer > p, #module1 > p, #module2 > p {}”, whereas I can just add a class to my new element.

    And specificity isn’t just a problem for big teams. I and several devs I’ve talked to (and seen on sites like Stack Overflow) have hit the same issues when working solo or in small groups. Specificity isn’t particularly difficult, but why add one more obstacle to your own path?

  24. I agree overall with the point of view in this article and the comment by @Neal G made above.

    For me personally, I’m wary of targeting elements based on #id because the CSS validator always warns me not to.

  25. So, what exactly are the reasons to to ever use an id instead of a class?

    Semantics?
    Why is an id more semantically appropriate than a class? They both describe the purpose of the element. Most users won’t know whether you’re using an id or a class, so you must be talking about accessibility. So where is it documented that id provides better context for screen readers etc. than class? I can’t find it. I’d love to read about that if you have any examples.

    Bandwidth?
    I assume you mean a selector performance difference, which dozens of sources state is negligible. The most ardent supporters of reduced use of classes are those working on masssive sites where performance would be the biggest issue. Or do you mean bandwidth in some other sense, like communication bandwidth? In that case, see the above. “Class”, “Id”, they’re just words. Does the # before the name somehow communicate more?

    Using an id does one thing that a class doesn’t: it is much much more specific. More than 200 times more specific, therefore much more difficult to override. And much less flexible, because you can only use one of each per page. So without any clear advantage to using an id over a class, why bother?

  26. Jeffrey, regarding descendant selectors, I agree with some of your points. I think it’s good practice to use them, and even Nicole Sullivan’s media object uses the descendant selector, so that’s not a problem. The main issue in reference to OOCSS and the Harry Roberts article you linked to is the issue of avoiding IDs.

    To resolve this, you just need to answer the following question: What can you do with an ID, that you can’t do with a class? Once you answer that, and you factor in all the negatives that come along with IDs, then you’ll understand that it’s never correct to use an ID as a styling hook, and it’s always correct to use a class.

    You also mentioned that it’s a “waste of bandwidth” and “bad form” to add classes to paragraph elements. To be honest, I don’t even know what “bad form” means. But I suspect it’s one of these antiquated “keep your markup clean” notions to which, unfortunately, too many people are clinging for no good reason.

    We’re not writing poetry. Code should solve problems. If adding classes to all paragraph elements solves the problem of hard to maintain CSS, then I’m all for code with “bad form”. And the bandwidth problem? Well, I’ll just quote Paul Irish, from his article “box-sizing: border-box FTW”:

    “[Y]ou are not allowed to care about the performance of * unless you concatenate all your javascript, have it at the bottom, minify your css and js, gzip all your assets, and losslessly compress all your images. If you aren’t getting 90+ Page Speed scores, it’s way too early to be thinking about selector optimization.”

    In other words, HTML and CSS performance is moot if you haven’t yet solved those other bandwidth issues. So I say, if “bad form” means “good performance”, then “bad form” should be a web development best practice.

  27. Agree 100%. While strict code style guidelines like OOCSS are great for lagre sites I am concerned that CSS devs are just learning to sidestep the cascade instead of understand it. There are so many selectors with different degrees of importance and understanding how they behave and override each other can be an incredibly powerful.

    There are already rules in place that make IDs the most specific part of HTML and JavaScript. They can only be used once on a page so it is logical that they are scored so highly by the CSS specificity algorithm. It’s not quite as strict as !important but if use correctly it effectively is a way to safely namespace !important styles. I don’t write CSS this way but it is totally valid and can even be leveraged to ease some pains of large projects. No part of any language should be completely discounted of all its merit.

    I would love to see CSS devs stop side-stepping selector specificity and start embracing it. Plenty of ways to write smaller, cleaner code that uses more than just classes.

  28. So, what exactly are the reasons to to ever use an id instead of a class?

    Chris:

    CSS doesn’t live in a vacuum. It’s coupled with HTML. Semantic, structural HTML serves several purposes, among them accessibility across devices with varying capabilities, and “SEO”/findability. Building on a strong foundation of semantic, structural HTML and using progressive enhancement to add visual and behavioral layers means that your web content will be available regardless of the capabilities of the device that is used to access it, and the abilities of the person using that device. You achieve these good things by understanding HTML and using it appropriately, as it was designed to be used.

    Clear semantics in markup serve another purpose, too: though a person using your site doesn’t see them, a colleague working on it does. Whether you’re handing off markup to a successor when you leave your job, or working with a collaborator, the more your HTML and CSS labels and practices clearly identify the various elements of your site and page structure, the more quickly your collaborator or successor will get up to speed, and the less likely you are to create the kind of “too many cooks/no clear roadmap” situation that often besets large sites and that, if not prevented from the get-go, may require OOCSS. (But this is like amputating a leg instead of preventing diabetes by adjusting diet.)

    “Humans first, machines second” is one of the thoughts behind Microformats, and that thought is a good practice generally. If I can understand your markup by looking at it, there’s a good chance it’s well organized, will behave correctly, and will be susceptible to smooth updates as opposed to the kind of clusterfucks that give rise to harsh, desperate “rules” like “never use ID.”

    Using ID on an element that occurs once and that serves a structural role is a good way of highlighting that element so your collaborative colleague (or successor) understands immediately that the item serves an important, non-repeating structural role such as primary navigation, footer, and so on.

  29. I would love to see CSS devs stop side-stepping selector specificity and start embracing it. Plenty of ways to write smaller, cleaner code that uses more than just classes. … I would love to see CSS devs stop side-stepping selector specificity and start embracing it. Plenty of ways to write smaller, cleaner code that uses more than just classes.

    Hear, hear! Thanks, Scott. That is better articulated than what I wrote here, and the most important rationale of all for learning about and properly using ID instead of dismissing it out of a misguided sense that what is true for OOCSS on large sites is true generally.

  30. @Scott Kellum, you said:

    There are so many selectors with different degrees of importance and understanding how they behave and override each other can be … incredibly powerful.

    In what way can they be “incredibly powerful”? I understand what you’re trying to say, Scott, but unfortunately there is no evidence to back this up, and tons of evidence to the contrary. Higher specificity does not equate to ‘namespacing'; it equates to bad code, because now instead of allowing the cascade to work naturally, you’re disrupting the cascade, which is what IDs and !important do.

    Again, read my previous comment: There’s no reason why you can’t just do “div class=footer” instead of “div id=footer”. The class does exactly the same thing as the ID, except without the super-high specificity. You don’t need high specificity if you are not overriding anything. Start with classes in all cases, and the cascade will work its magic naturally, from top to bottom in your stylesheet, without any specificity problems. Specificity, although being a ‘valid feature’ of CSS, is actually a hindrance to maintainable code.

    You also said:

    No part of any language should be completely discounted of all its merit.

    Tell that to Douglas Crockford and the thousands of developers around the world who have “discounted” many parts of the JavaScript language, all for our benefit, because, well, most (all?) of what Douglas recommends in his books and talks are actually bad — even though they are “valid” parts of the language.

  31. @Louis Lazaris

    To rebut your statement, “There’s no reason why you can’t just do “div class=footer” instead of “div id=footer”. The class does exactly the same thing as the ID, except without the super-high specificity.” I put this together: http://codepen.io/scottkellum/pen/ptJqh

    And my personal CSS style at the moment doesn’t use IDs, but it does use specificity to manage generic modifiers vs module+modifier: http://codepen.io/scottkellum/pen/jdliH

    IMO specificity is a huge part of CSS weather you fight it, use it, or side-step it. IDs aside, everyone who writes CSS deals with specificity. All I am saying is there is a reason for specificity and a good reason why IDs are ranked so high. Because of this, IDs need to be use carefully if ever but I think saying they shouldn’t be used ever is going too far.

  32. Classitis is a disease. That said, there are no absolutes, either way.

    For the people talking about reusability as a reason to only use classes – I would say that it’s just as likely to be a problem the other way. In other words, what happens when you use classes so the CSS can be used in various spots – then you decide that you want those paragraphs over there to be different from the paragraphs over here?

    In other words – if I have “.thisbox > p” in two places – what happens when I want the Ps to be styled differently? You have to go back and change everything – which is exactly what re-usability folks are saying they are trying to avoid in the reverse. So if I have “#thisbox1 > p” and “#thisbox2 > p” – even if they are styled the same at first – duplicate code – you may want to change it later.

    And then, if you tell me that “#thisbox1″ and “#thisbox2″ – could just as easily be classes … then that’s true … but then what’s the point on re-usability?

    Point is that IDs and Classes are a way of organizing code. IDs are for unique semantic segments of HTML – and Classes are for pieces that may be needed more than once. It’s a way for you to keep them straight. The fact that they may be styled similarly now or later is a separate issue. The HTML should be semantically, organizationally and philosophically correct – and the CSS should flow from that. It’s an approach that helps you organize your code better – IMO.

  33. I really liked this article, though to a certain extent I don’t understand the arguments going on, in particularly not the incredible… excuse my expression “fanaticism” that I see showing up when it comes to ID vs no-ID.

    “you’ll understand that it’s never correct to use an ID as a styling hook, and it’s always correct to use a class”

    This is what I mean by fanaticism. Perhaps some people feel that it is never correct to use an ID, perhaps most people feel it. But to stand up and go “you are an idiot because you have not understood the gospel of the no-ID” is a lot less useful.

    For me, I nowadays swear by pre-processors, so though I understand the reusability issues, I handle it, as someone else noted, through the use of mixins and such, which might be the second reason that I don’t quite understand the dogmatism I’m seeing.

    Overall, I feel that if a hook is already there, use it! So, someone mentioned ARIA markup – I agree, use that if it fits what you need (it’s what I use nowadays on my own projects). You already need an ID because you’re using it to target javascript? Then use that as a hook.

    So my feelings are summed up as the following: Add what you need, keep an eye on reusability, but don’t add a class when you already have something else that is usable.

  34. @Scott Kellum:

    No disrespect intended here, but your example is not realistic. Nobody is going to write CSS like that! :) For example, why would you even need 10 chained classes on that element? I know it was just for demonstration purposes, but if something is not real-world, then it really is not a valid argument.

    Besides, in OOCSS, its encouraged to extend modules by adding classes, but not chaining them. In order to make that example realistic, you’d have to have have something like 10 other selectors prior to the big chained one — just to demonstrate why you’d even have that in the first place.

    Chaining classes is pretty much the same as using IDs; they add more specificity, so you should avoid them (except maybe much lower down in the DOM tree, where they would not cause specificity issues, similar to descendant selectors). If you change that example to use chainless class selectors, the problem goes away.

    Nonetheless, I have a feeling we’re just going to agree to disagree here, which is fine. But next week I’m going to be posting something on my blog about this (maybe a screencast), because I really think a lot of developers, including Zeldman in this post, are still looking at this the wrong way.

  35. Louis, ID and CLASS have different semantic weight. If my page has one footer, giving it an ID of footer is appropriate. Giving it a CLASS of footer undervalues it, misrepresenting it as one of many possible page footers. ID is the more appropriate choice in this case. ID has greater specificity for a reason. Markup semantics matter. CSS does not exist in a vacuum.

    (Of course, if your page has multiple footers, you’re in HTML5 land and should be using HTML’s new FOOTER element instead of a div.)

  36. @Jeffrey:

    Whatever “semantic value” you want to get out of “#footer”, you can also get out of a class name. You seem to be implying that when a developer sees “.footer”, they automatically assume it’s applied in more than one place. But that’s just a remnant of the old-school methods where IDs were for single elements and classes were for multiple.

    You want a class to have “semantic value”? Then name it in a way that implies it’s unique. One of the following might accomplish this:

    .footer-main { }

    .id-footer {}

    This way, you’re avoiding the sledgehammer-specificity of the ID, and you have the added bonus of being able to extend those existing classes with add-on classes, should the need arise.

    But the most important benefit is that, if you ever want to, you can now reuse one of those styles. Yes, it’s true that in this case you’re not planning to reuse the styles, but if you’re encouraging people to think this way for a footer element, then they’re probably also going to think this way for other “unique” elements too, and all the while they’ll miss the advantages that come from abstracting styles (which you can’t do with IDs).

    In the case of a lone footer, it probably won’t matter. But that’s why it’s even more bizarre why some developers are so set on using an ID for a lone header or footer. Like I said, you can have a unique class name, and you can even use the descendant selector with the class name. This way, you run little to no risk of specificity problems and the “C” in “Cascading Style Sheets” starts to have meaning — because classes lower down in your stylesheet will have more weight than those above them.

    True, this probably means nothing in the case of a single header or footer, but it all boils down to the fact that classes can still be unique, so you might as well just use a class.

  37. Further on this, you said:

    ID has greater specificity for a reason.

    That reason has nothing to do with maintainability, readability, or semantics. Unless you can show me something from the W3C spec that says that IDs must be used otherwise your documents aren’t “semantic”, and unless you follow that up with some kind of practical real-world benefit this provides, then this argument doesn’t really hold any water.

    I don’t know who came up with IDs as selectors, but it might be the same person who came up with global variables and eval in JavaScript. :)

  38. @Louis Lazaris

    Maybe we should agree to disagree. We have been here before. I see what you are saying and respectfully disagree. I hope you at least see it the same way.

  39. Whatever “semantic value” you want to get out of “#footer”, you can also get out of a class name. You seem to be implying that when a developer sees “.footer”, they automatically assume it’s applied in more than one place. But that’s just a remnant of the old-school methods where IDs were for single elements and classes were for multiple.

    Louis:

    ID for single elements and classes for multiple isn’t an “old-school method.” It’s how the elements are defined in HTML. A correct understanding of HTML is not “old-fashioned.” Nor is it “old-fashioned” to use HTML elements as the W3C intends them to be used. It is actually rather important to do so — just as it is important for a writer to understand grammar and an engineer to grasp physics.

    Now, it is possible to code without understanding or appreciating the rudiments of HTML. Indeed, one can become a fairly advanced coder, making web pages go loop-de-loop, using frameworks creatively, and so on, without actually knowing and respecting the basics of HTML. I am afraid that more than a few web developers are doing just that — honing advanced skills without first understanding and fully appreciating the important basics of structural HTML. My post was in part motivated by a desire to push back against the viral uptake of misinformation.

    Of course a love of the power of code minus a respect for (or understanding of) the immense true power of HTML has been the web’s besetting sin since the first table layout. It’s been the norm for much of the web’s history for developers to build cool stuff on a lousy, unstable framework, and dismiss the very notion that HTML semantics matter. For a time, in the 2000s, we were able to change that perception, and, thankfully, a lot of folks in our industry still believe in the value of accessible, semantic markup. I worry about the ones who don’t, but you can’t save everybody.

  40. I never understood why people hated ids and using id in CSS.
    I’m a fan of semantic HTML. If the element is on the page once, I use a semantic id. If the element is repeated, I use a semantic class.

    I also think that, for the browser, computing a style like “#footer li” is much faster than “li.footer”, because the scope of its search is limited to the “#footer” element, and not all of the DOM. Am I crazy?

  41. Thank you, your timing is uncanny! I just had to defend my method of using an id in a particular way that I do, because the engineer has the idea that id’s are for scripts and classes for css. I use id’s in a certain way that allows me to get at exactly what I need when required. I won. Nice to see the gawdfadda backs me up. ;)

  42. @Jeffrey:

    First of all, I think this is a healthy debate and I don’t mean any disrespect by any of this. As Scott mentioned, we’ll probably ultimately agree to disagree, so I’m fine with that.

    Second, another comment I posted here seemed to have disappeared (probably went straight to spam, despite there being no links).

    Finally, to use your own expression, I respectfully call “bunk” on your definition of “semantic” HTML. This discussion is not about applying IDs to elements in the HTML (which I fully comply with). This is about whether or not those IDs should be used in stylesheets as styling hooks.

    Therefore, this has zero to do with “semantics”. Machines don’t read IDs. To quote Mark Pilgrim from his HTML book:

    “The div element has no defined semantics, and the id attribute has no defined semantics. (User agents are not allowed to infer any meaning from the value of the id attribute.)”

    So having a basic knowledge of HTML, and semantics, you yourself should know this, and shouldn’t tell your readers that using an ID is “more semantic”.

    And here’s what the spec says on IDs:

    Document languages may contain attributes that are declared to be of type ID. What makes attributes of type ID special is that no two such attributes can have the same value in a conformant document, regardless of the type of the elements that carry them; whatever the document language, an ID typed attribute can be used to uniquely identify its element.

    What this says has no relevance to semantics. This is merely stating that an ID cannot be reused in the HTML. And this is because of the use of IDs as fragment identifiers (a concept that would be worthless if there was more than one ID per page). The uniqueness of IDs, therefore, is not relevant to a “semantics” debate, nor are developers required to use IDs in order to comply with the spec, as you are implying.

    Just to clarify what you said, here is the relevant part, from your previous comment:

    ID for single elements and classes for multiple isn’t an “old-school method.” It’s how the elements are defined in HTML. A correct understanding of HTML is not “old-fashioned.” Nor is it “old-fashioned” to use HTML elements as the W3C intends them to be used.

    This conversation is not about using IDs in HTML; it’s about using IDs in CSS. The spec does not require that “unique elements” be targeted via ID selectors, just like the ECMA specification doesn’t require that developers use global variables in JavaScript. Those are features of the language that we have the option to use, but that we can refuse to use if we find they cause us problems. ID selectors are just one kind of selector. We can avoid them the same way we might avoid using “:first-child”. It’s an option we have.

    Again, go ahead and put unique IDs on all your unique HTML elements — that’s not a problem, and is well in line with the spec. My argument here is that you should use not use IDs in your CSS files, because targetting those elements with classes is better for the maintainability of your stylesheets.

  43. Classes are great! So are ID’s. You’ll benefit from both in harmony within the same stylesheet(s) in the long run. I have the habit of prefixing my classes. Because there’s always a chance that a webtemplate needs to be implemented in another CMS or shopping cart somewhere in the future. That CMS or shopping cart is going to have it’s own classes. Count on third party modules/ extensions with their own classes as well. The odds of running into conflicting classes get greater when you skip ID’s entirely and define generic/ class names…

  44. Louis:

    Consider the argument clarified, and consider me schooled. From a human-readable perspective, I always considered the use of ID in connection with a non-repeating structural element to be more semantic than the use of a class on that element because of what it conveys to the person reading your markup. This was apparently a creative inference on my part, which the spec does not support. A beautiful feeling murdered by a heartless fact. However, in fairness to my point of view, I like what Matt Newman said on your article :

    It’s also worth considering that to gather data about what new elements to add to HTML5 that IDs of millions of documents were parsed! No semantic value huh? Only lead to be a part of the justification of creation of a new set of semantic elements.

    He is right. Had Tantek and Eric and Doug and Ethan and I and others not used ID in this way, and had thousands of other designers and developers not followed our lead, the framers of HTML5 would not have had the data they had, and we very likely would not have the new semantic HTML5 elements we have today, whose use moots your point and mine (because using a footer element is better than using a div of ID footer or a div of class footer).

    In any case, I also finally see what you are saying, keeping the argument strictly to CSS. If ID creates a problem and CLASS does not, prefer the element that does not create a problem. I’ve always valued the practical over the theoretical, so I agree with where you are coming from. ID has never, to my knowledge, created a problem for the maintainability of my/our stylesheets but once a site is released to a client, who knows?

    Good food for thought, and I wish every person saying “don’t use ID” was as articulate and as standards-aware as you are.

    Again, go ahead and put unique IDs on all your unique HTML elements — that’s not a problem, and is well in line with the spec. My argument here is that you should use not use IDs in your CSS files, because targetting those elements with classes is better for the maintainability of your stylesheets.

    Fair enough!

  45. To the surprise of just about nobody, I’m going to bring a little bit of history to this.

    IDs, like classes, predate CSS by quite a bit; veterans of the era may remember the classic “<P ID=z23>”, which first appeared in HTML 2.0. The intent was to be able to mark a fragment of a document as a unique target, addressable and jump-to-able via URL fragments.

    When CSS came along, it looked to HTML and saw that class and ID existed as element-independent markers, so selectors were devised to hook into them. And because one of those hooks was unique and the other not, the selectors addressing them were given different weights. That seems pretty sensible to me, as much today as it did back then.

    If you dislike the specificity difference but still want to latch onto ID values for styling, use the attribute selector variant (‘[id="foo"]’), which has 0,0,1,0 specificity, the same as a single class name. That levels the playing field fairly well, even if it does require a bit more typing than just plain old #foo.

  46. @Jeffrey:

    No problem. I’m glad this didn’t just turn into a pointless mudslinging contest. I respect the fact that you’re willing to concede a point. I do it regularly in comments on my own site, and I know it’s not an easy thing to do. :)

    Thanks for the dialog.

  47. I honestly don’t understand what the big fuss is about. It’s a discussion between purity and practicality, where both methods’ pros and cons are neglectible in light of bigger issues on the web.

    Furthermore, I’d like to add that the majority of the web’s content (HTML) is produced by CMS systems, which very often means that the CSS cascade (specificity) is a blessing, not a bad practice. Speaking of being practical, I guess OOCSS overlooks that real-world fact.

  48. Again Jeffrey Understands the issue as only someone that has history in web-projects can.

    One of the commenters at the top wrote…
    “any CSS written for an #id can’t be used elsewhere.”
    Well that is the worst point to be made isn’t it… ID’s are for use-once objects, not re-usable objects. the probably not used anymore getElementById() exemplifies this as it only returns a single DOM element.

    Classes, not Id’s or any other silly construct are the CSS to be used in re-usable objects, and allow a high-degree of ooping CSS through chaining.

    Modern sub-genres of CSS I couldn’t care LESS about. JS + CSS can take care of anything LESS or similar nonsense comes up with. I just wish some developers would learn more about CSS, DOM and JS rather than getting a woody for useless new technologies!

    On the above statement, it is easier to write some dom with params that js or PHP builds CSS with than write an entirely new syntax…

  49. I’m in favour of using id’s for unique stylings :
    In the case of re-using css elsewhere – if your selector is tied to an id & you want to re-use it, you know it’s only used in one place on each page & so it’s relatively simple to change it to a class.
    If it’s tied to a class and you want to update it place on the page, you have more checking to do to make sure it’s not been (mis)used elsewhere – semantically not a problem, unless someone else disagrees on the meaning of the class.
    (although I mostly write css to ‘tidy up’ websites I use regularly, not for others, so mostly I have no access to change the html anyway)

  50. I’m in favour of using ID’s in this way and I normally work on CSS only on solo projects, or sparingly in a team.

    They solve a problem and things that solve problems are good. It’s up to you as the decision maker as to which solution you use to your problem and using ID’s in useful in many situations.

    But, as pointed out, it should be used ‘semantically, structurally & sparingly’

  51. If you’ve been in this business long enough, you should know how and when to use ID/Class for your css, and to claim that “is hard to maintain css with using ID” means that you/your team are probably using it the wrong way.

  52. Quote Louis Lazaris: “No disrespect intended here, but your example is not realistic. Nobody is going to write CSS like that! :) For example, why would you even need 10 chained classes on that element?”
    Ahahahahaha… anything spat out by Drupal? Here’s one that’s rather clean:
    <div class=”views_slideshow_wh_slide views_slideshow_slide views-row-2 views_slideshow_wh_hidden views-row-even” id=”views_slideshow_wh_div_popular_topics-block_1_1″><div class=”views-row views-row-0 views-row-first views-row-odd”>

    or

    <div class=”topnav-dd-outer topnav-dd-outer-two-col topnav-dd-outer-featured topnav-dd-outer-two-col-featured”>

    (whitehouse.gov)

    I’ve seen worse, usually with more classes with shorter names. I think the record for me personally was 12.

  53. While agreeing with the notion of moderate ID usage in conjunction with other rules, it seems JS uses more IDs than CLASSes, so IMO combining style and functionality in one selector causes debugging to be harder.
    As a matter of principal, I prefer leaving style to the classes and functionality to the ids (considering id usage in case of unique places, e.g. footer, header).

Comments are closed.