Grow your CSS skills. Land your dream job.

Multiple Class / ID and Class Selectors

Published by Chris Coyier

Can you spot the difference between these two selectors?

#header.callout {  }

#header .callout { }

They look nearly identical, but the top one has no space between "#header" and ".callout" while the bottom one does. This small difference makes a huge difference in what it does. To some of you, that top selector may seem like a mistake, but it's actually a quite useful selector. Let's see the difference, what that top selector means, and exploring more of that style selector.

Here is the "plain English" of "#header .callout":

Select all elements with the class name callout that are decendents of the element with an ID of header.

Here is the "plain English" of "#header.callout":

Select the element which has an ID of header and also a class name of callout.

Maybe this graphic will make that more clear:

Combinations of Classes and IDs

The big point here is that you can target elements that have combinations of classes and IDs by stringing those selectors together without spaces.

ID and Class Selector

As we covered above, you can target elements by a combination of ID and class.

<h1 id="one" class="two">This Should Be Red</h1>
#one.two { color: red; }

Double Class Selector

Target an element that has all of multiple classes. Shown below with two classes, but not limited to two.

<h1 class="three four">Double Class</h1>
.three.four { color: red; }

Multiples

We aren't limited to only two here, we can combine as many classes and IDs into a single selector as we want.

.snippet#header.code.red { color: red; }

Although bear in mind that's getting a little ridiculous =)

Example

So how useful is all this really? Especially with ID's, they are supposed to be unique anyway, so why would you need to combine it with a class? I admit the use cases for the ID versions are slimmer, but there are certainly uses. One of those is overriding styles easily.

#header { color: red; }
#header.override { color: black; } 

The second targets the same element, but overrides the color, instead of having to use:

.override { color: black !important }

or perhaps prefacing the selector with something even more specific.

More useful is multiple classes and using them in the "object oriented" css style that is all the rage lately. Let's say you had a bunch of divs on a page, and you used multiple various descriptive class names on them:

<div class="red border box"></div>
<div class="blue border box"></div>
<div class="green border box"></div>
<div class="red box"></div>
<div class="blue box"></div>
<div class="green box"></div>
<div class="border box"></div>

They all share the class "box", which perhaps sets a width or a background texture, something that all of them have in common. Then some of them have color names as classes, this would be for controlling the colors used inside the box. Perhaps green means the box has a greenish background and light green text. A few of them have a class name of "border", presumably these would have a border on them while the rest would not.

So let's set something up:

.box { width: 100px; float: left; margin: 0 10px 10px 0; }
.red { color: red; background: pink; }
.blue { color: blue; background: light-blue; }
.green { color: green; background: light-green; }
.border { border: 5px solid black; }

Cool, we have a good toolbox going here, where we can create new boxes and we have a variety of options, we can pick a color and if it has a border or not just by applying some fairly semantic classes. Having this class name toolbox also allows us to target unique combinations of these classes. For example, maybe that black border isn't working on the red boxes, let's fix that:

.red.border { border-color: #900; }

Border color on red box changed because it had both the red class and border class

Based on this demo page.

Specificity

Also important to note here is that the specificity values of selectors like this will carry the same weight as if they were separate. This is what gives these the overriding power like the example above.

Browser Compatibility

All good current browsers support this as well as IE back to version 7. IE 6 is rather weird. It selects based on the first selector in the list. So ".red.border" will select based on just ".red", which kinda ruins things. But if you are supporting IE 6, you are used to this kind of tomfoolery anyway and can just fix it with conditional styles.

Comments

  1. Chris
    Permalink to comment#

    Thanks for this great overview ;)

  2. You’ve flipped the initial descriptions, though the graphic that follows it is right. `#header.callout` is the element with both id=”header” and class=”callout”, while `#header .callout` is child with class=”callout” of the element with id=”header”.

  3. Permalink to comment#

    Same as Chris – you’ve got the descriptions the wrong way round..

  4. Wow! This is great. This is the first time I’ve ever heard of this combination of selectors. It will be extremely helpful in helping to reduce divs within divs. Great post. Thanks.

  5. That is a great review of selectors and the differentiations between them. Thanks!

  6. fludotlove
    Permalink to comment#

    As Chris Pratt said, you have mixed up the plain English versions of your classes.

    Nice article nonetheless. Thanks.

  7. Permalink to comment#

    I’ll have to revisit these id + class rules. We started using a lot of these at the last job – then removed them all when they weren’t working as expected in IE6. I never realized that IE6 was just using the first selector. Since I use a conditional stylesheet for IE6 anyway – this seems like a great option to go back to.

    Does this happen to anyone else? Whenever I find something like this that doesn’t work in every browser, I put up a kind of mental block that won’t allow me to use that technique anymore – never thinking up a simple way around it.

  8. k-on
    Permalink to comment#

    according to CSS The missing manual second edition

    “When more than one style applies
    to a tag, a web browser must
    determine which style should “win
    out” in case style properties
    conflicts. In CSS, a style’s
    importance is known as specificity
    and is determined by the type of
    selectors used when creating the
    style. Each type of selector has a
    different value, and when multiple
    selector types appear in one style—
    for example the descendent
    selector #banner p—the values of
    all the selectors used are added up.”

    example:
    selector id class tag total
    p 0 0 1 1
    .byline 0 1 0 10
    p.byline 0 1 1 11
    #banner 1 0 0 100
    #banner p 1 0 1 101
    #banner .byline 1 1 0 110
    a:link 0 1 1 11
    p:first-line 0 0 2 2
    h2 strong 0 0 2 2
    #wrapper #content .byline a:hover 2 2 1 221

  9. k-on
    Permalink to comment#

    and this cause override and not” prefacing the selector with something even more specific.”

    right?

  10. Permalink to comment#

    Thanks for the article. It gave me a ton of wonderful ideas for a couple of sites I am working on and saves me a ton of span tags.

  11. David Hucklesby
    Permalink to comment#

    You said: “IE 6 is rather weird. It selects based on the first selector in the list.”

    I believe that would be the last selector in the list, no?

  12. Stephan
    Permalink to comment#

    Thanks for this information!

  13. Permalink to comment#

    Great site! Beautiful and usefullllllllll tutorials for me. sorry for myself because i see here now!thanks a lot!

  14. Permalink to comment#

    Really cool article. Can’t wait to give this a try :)

  15. This is not a every day usage stuff, how did you found out :D This one is cool: #header.callout

    Thanks for sharing.

  16. Dyllon
    Permalink to comment#

    Wow, I was wondering where you where going with that. But, considering that IDs should only be used once per page, shouldn’t the ID be good enough to specify?

    • In most cases yes, but I talked about a specific example above. In more detail: Perhaps you had a h2#comments on every single page of your site. On one of them you wanted to change up the styling a bit. You could add a class name, then use the double-selector to override any existing values it had. You wouldn’t need to rely upon !important rules then, or any more specific selectors.

  17. Eddy
    Permalink to comment#

    Hey Chris, you wrote “children” but meant “descendants”. Children are selected with the “greater than” sign like this E > F

  18. Permalink to comment#

    Thanks Chris! IE6 and tomfoolery in the same sentence. I dig your vernacular.

  19. Great stuff, I actually learned something :). Thanks.

  20. Ulyses
    Permalink to comment#

    Just a thought, I believe a more clear (but not really real) example would be:

    HTML

    Chapter 4
    Adventure begins
    That day...

    CSS

    p {color: black}
    p.title {text-decoration:underline}
    p.title#chapter4 {text-transform:uppercase; background-image: url(4.jpg)}
    • Ulyses
      Permalink to comment#

      Just a thought, I believe a more clear (but not really real) example would be:

      HTML

      Chapter 4
      Adventure begins
      That day…

      CSS

      p {color: black}
      p.title {text-decoration:underline}
      p.title#chapter4 {text-transform:uppercase; background-image: url(4.jpg)}

    • Ulyses
      Permalink to comment#

      And I say that because .box class in Demo could is, in fact, the div element. And so on.

      But, I don’t know if I blame the example or is something fishy here.

      It’s pretty clear to me that, if you create a different class for an html element, you will have different CSS mark-up opportunities.

      Even more, I’d say, that you are putting together here, an example of HOW NOT TO cascade…?

  21. Permalink to comment#

    Only the day where we can use more than two classes… ahh..

  22. Actually we use this everyday on some old school, dynamic drop down menus. The div id to style the container, and the multiple classes to style the li, and a tags in the menu. Since there are times we need the same menu system on a site twice, we can have one menu styled with the classes, and one menu over-ruled using the id.

    Each menu has a different id, but for them to work they both need the same classes.

    On my freelance stuff, I use this stuff on heading tags all the time. So you would have h1.red or h1.blue…stuff like that. There are other cases, but this one comes to mind right off the bat.

  23. Permalink to comment#

    Useful, as usual.
    Great explanation!

  24. Permalink to comment#

    Wow Chris, great explanation!
    I never knew that and now that I do, I can see how useful this could be.

    Thanks.

  25. I constantly use multiple selectors like this, especially with jQuery. I add a class to the container so something like #some-container.added-class .child-selector really helps, and is much easier than just adding classes to everything (and faster).

    I also bet that in HTML5, people will be doing this a lot. For example:
    header.main { styles for main header }
    since you wouldn’t want to just style the header element itself, as it’s used for other purposes as well.

    • Permalink to comment#

      No need to. A cleaner(or at least in my opinion) would be using child selectors like:

      body > header { styling }

      And for the other headers you would use something similar or simply

      div header { styling }

      Where we assume you use 1 styling div for the main container. Could also be article or section or whatever floats your boat.

      IE6 is the only one that doesn’t natively support > (which is CSS2) but you’d need JS to support HTML5 in IE anyway.

  26. Permalink to comment#

    Read the article this morning. I thought it was cool, but couldn’t imagine using it.

    …Of course I ended up using it just now to solve to a selector issue.

    Chris, you have an uncanny way of publishing articles at just the right time!

  27. Thanks for this info. I didn’t know this about css selectors.

    Good old IE always causing problems, go figure.

  28. Permalink to comment#

    Nice article… Great explanation!

  29. Mads Brunn
    Permalink to comment#

    I heard about this technique some time ago and loved it because it greatly reduced the amount of markup. I tried it out on a few of my sites but had to give up on it because of the issues with IE6.

    Could you give some examples on how to solve the IE6 issue using conditional styles.

    How would you e.g. solve the IE6 problem in your box example without adding extra markup?

  30. Really useful to remind, thanks.

  31. Permalink to comment#

    Thank you for this, Chris.

  32. Permalink to comment#

    The best explanation of specificity I ever read was CSS: Specificity Wars, which gives a really useful way of remembering specificity rules using Star Wars characters…

  33. Simon Bainbridge
    Permalink to comment#

    That was a very helpful post as I did realise there was a difference with using a space or not.

    I also did not realise that you can declare multiple class names inside one set of quotation marks. i.e class=”class1 class2″

  34. marc
    Permalink to comment#

    although it won’t make your html any prettier, you can select the last #id.class in ie6 by stacking the classes in the markup:

    style:

    div#something { color: orange; }
    div#something.foo { color: red; }
    div#something.bar { color: blue; }

    html

    this will be red.

    this will be blue

    this will also produce blue in firefox.

    i’m also curious about seeing the issue solved with conditional styles. not seeing how to use #id.class in ie6 using conditionals off the top of my head. or the bottom, for that matter.

    • marc
      Permalink to comment#

      hrm. sorry; total newb. i wrapped that in pre but it didn’t come out correctly. anyway:

      div id=”something” class=”foo”

      div id=”something” class=”foo bar”

      second example will produce blue. first will be red. no class, of course, will be orange.

  35. Billy
    Permalink to comment#

    One use I see of this is with a CMS like Drupal. Drupal attaches class names based on the contents of the page to elements with ids. For example, if you have a sidebar visible, the #wrapper div will get a “left-sidebar” class. On a page with no sidebar, the class isn’t present.

    I can see this being the best way to style an element based on page content in a system like that.

  36. flash
    Permalink to comment#

    I thought #header.callout was a typo!

    Thanks Chris – learnt something new today!

  37. Permalink to comment#

    Perfect! Thanks Chris I emailed you a post cast wish for more advanced selecting like this and this was exactly what I was thinking. What you do so much better than most is note the code, illustrate visually the code, and then give us some strategy. Thanks again.

    (I would like to add to my wish list – taking these type of concepts to wordpress. I am having issues learning how wp regenerates the tags you place around the loop and getting the selectors right.)

  38. Permalink to comment#

    Great article, thanks for the info.

  39. For those who actually want to get this to work in IE6, I found this link which explains how:

    http://bytesizecss.com/blog/post/the-idclass-selector-in-ie6

    You would have your container div with an id and a class, THEN a blank div (no id or class), THEN your content.

    Your css would be this for IE6 to work:
    #header.callout div {styles}

    • Permalink to comment#

      When I wrote that bytesizecss article, I didn’t mean for people to think that only a ‘div’ element with no id or class is the solution.

      It could be any element and it could have a class and/or an id. You just need to add a child element basically. For example, the following would work fine:

      Hello

      Hello

      Hello

      .button span {
      color: #000;}

      .button.highlight span {
      color: #ccc;}

      .button.lowlight span {
      color: #f00;}

    • Permalink to comment#

      hm, that was an epic fail. The HTML should have been like this:

      <a href="#" class="button"><span>Hello</span></a>

      <a href="#" class="button highlight"><span>Hello</span></a>

      <a href="#" class="button lowlight"><span>Hello</span></a>

  40. Permalink to comment#

    This is the right place to learn.

    Thank you !

  41. Willliam Valencia
    Permalink to comment#

    Hey Chris
    Can you do an article explaining how Stacking Classes works? I found this article that talks about it but it does not explain how it is used nor show examples of how it works. Here is the link to the article and a snippet of what he describes.

    Thanks so much your articles are always so well done and easy to grasp.

    Link:

    http://blog.jm3.net/2007/03/16/the-only-ten-things-to-know-about-css/

    Snippet:
    Stack your classes: no one EVER uses this trick; you can apply as many css classes to a single tag as you want, just put spaces between the names, like will apply both the class exciting AND the class warning. this saves TONS of duplication in your CSS. (i don’t know why no one uses this trick. it’s great. when you see someone’s stylesheet that has dozens of lines like: .redtext { font-family: Arial, Helvetica, sans-serif; color: red; } .bluetext { font-family: Arial, Helvetica, sans-serif; color: blue; }, that’s a sign that they probably don’t know this trick.

  42. Permalink to comment#

    Nice article, I think combining classes and ids is very useful.

  43. Ulyses
    Permalink to comment#

    I’ve confirmed my hunch.

    After a long time spent I’ve come to the following conclusion: this is for amateurs, building classes over classes (that will only make you wonder “what did I wanted to to here?”).

    There is a better, cleaner way, using just one CSS declaration. Do you want to know how?

  44. Shahbaz Ahmed Bhatti
    Permalink to comment#

    Can u tell me please
    why it not working

    idname1{

    font-size: 29px;
    }

    idname2{

    font-size: 23px;
    }

    idname1, #idname2 p{

    margin-left: 77px;
    }

    i m trying to do but it not working

  45. meow
    Permalink to comment#

    I’m sorry but I really wish you wouldn’t flip around with the things. It makes it so confusing. Can’t you just stick to ‘the one with spaces first and the one without spaces second’ instead of mixing everything up? They are already so similar and mixing them up makes it that much harder to follow your post.

  46. pavan
    Permalink to comment#

    How to access elements inside a class using css selectors example

    one div with class
    div class=”something”
    then
    img tag inside class
    i need to chage img tag tell me how to access

  47. Sven Noel
    Permalink to comment#

    Awesome! Thank you! Here’s an interesting one that I keep coming across, but haven’t found an answer to:

    So, I have two classes, each with an additional class and/or selector. In the interest of being DRY, how would I write the selector to insure both are selected?

    The WET example:

    .page-id-1 header.entry-header { display: none; }
    .page-id-1 .entry-thumbnail { margin-top: -8px; }
    .page-id-2 header.entry-header { display: none; }
    .page-id-2 .entry-thumbnail { margin-top: -8px; }
    

    Desired DRY Example: (?)

    .page-id-1, .page-id-2 header.entry-header { display: none; }
    .page-id-1, .page-id-2 .entry-thumbnail { margin-top: -8px; }   
    

    Essentially what I want is to select multiple classes with multiple classes, but didn’t see that listed above.

    class or id 1 AND class or id 2, each with the class or id of OR element of { element: attribute; }
    

    Any ideas?

  48. Phil
    Permalink to comment#

    Good Stuff. A very helpful article for me.

  49. prabhagaran

    Superb. Thanks for the expantion of id and class combination usage.

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".