Multiple Class / ID and Class Selectors

Published
February 22, 2010
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:

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.

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

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 last selector in the list. So ".red.border" will select based on just ".border", 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.

Share On

Comments

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”.

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.

“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.”

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.

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.

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.

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.

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.)

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.

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.

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.

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

Treehouse is where you go to learn HTML, CSS, and how to build iOS apps. It's a complete education in modern web and app technology, designed to get you ready for a hot new job or to kickstart your own business.

The Lodge is a member login only area with access to video training on how to build websites from scratch using the best modern tools.

How many people touch the CSS in your current main project?

What now? I have some ideas for you.

Go explore CodePen!

As a front end designer and developer, you should have an account on CodePen so you can save your snippets, present your ideas, and engage with the rest other front end folk. I'd encourage you to go PRO as well, to unlock the full power of CodePen.

Get the newsletter!

You should sign up for the CSS-Tricks newsletter. It's a clean copy of all the blog posts each week, combined together, right to your inbox. If email isn't your thing, there is an RSS feed, iTunes, and lots of other ways to subscribe.

Listen to ShopTalk!

Subscribe to The Lodge!

The Lodge is a members-only, ad-free video learning area here on CSS-Tricks. Just like the free screencasts, but organized into four large complete series. Membership is also the #1 best way to support CSS-Tricks.

We can do the real footer now.

Site Links

Colophon

CSS-Tricks* is created, written by, and maintained by Chris Coyier. It is built on WordPress, hosted by MediaTemple, and the assets are served by MaxCDN. The fonts are Source Sans and Source Code Pro. It is made possible by viewers like you who subscribe to The Lodge and through advertising for products and services I like.