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 class
es and ID
s by stringing those selectors together without spaces.
ID and Class Selector
As we covered above, you can target elements with 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 class
es. Shown below with two class
es, 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 class
es and ID
s into a single selector as we want.
.snippet#header.code.red { color: red; }
Although bear in mind that’s getting a little ridiculous.
Learn more about how to select IDs, classes, and multiple classes at DigitalOcean.
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 class
es and using them in the “object oriented” CSS style that is all the rage lately. Let’s say you had a bunch of div
s 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 class
es, 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 class
es. Having this class
name “toolbox” also allows us to target unique combinations of these class
es. For example, maybe that black border isn’t working on the red boxes, let’s fix that:
.red.border { border-color: #900; }
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.
Learn more about specificity in CSS at DigitalOcean.
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.
Thanks for this great overview ;)
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”.
Just wanted to point that :)
The images show it right, though.
glad I wasn’t the only one going huh?
Actually #header .callout concerns the element(s) with the class = callout which is a/are descendant(s) (not child(ren)) of the element wit id=header.
For child elements it would be #header > .callout.
Right. “decedents” is the more-correct term.
Same as Chris – you’ve got the descriptions the wrong way round..
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.
That is a great review of selectors and the differentiations between them. Thanks!
As Chris Pratt said, you have mixed up the plain English versions of your classes.
Nice article nonetheless. Thanks.
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.
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
and this cause override and not” prefacing the selector with something even more specific.”
right?
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.
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?
Not in my experience so far… .red.border would select on .red, not .border
David is correct. In IE6 red.border is the same as .border so the border color will get applied as #900. Here is a screenshot of rendering in IE6.
That should have been .red.border is the same as .border
Just to add another voice, David and Ethan are correct regarding “.class1.class2 == .class2” in IE6. Although I’m unsure how it handles “#id.class”.
Yep, looks like this is correct, I misinterpreted what I was looking at.
Thanks for this information!
Great site! Beautiful and usefullllllllll tutorials for me. sorry for myself because i see here now!thanks a lot!
Really cool article. Can’t wait to give this a try :)
This is not a every day usage stuff, how did you found out :D This one is cool: #header.callout
Thanks for sharing.
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.
Hey Chris, you wrote “children” but meant “descendants”. Children are selected with the “greater than” sign like this E > F
Thanks Chris! IE6 and tomfoolery in the same sentence. I dig your vernacular.
Great stuff, I actually learned something :). Thanks.
Just a thought, I believe a more clear (but not really real) example would be:
HTML
CSS
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)}
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…?
Only the day where we can use more than two classes… ahh..
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.
Useful, as usual.
Great explanation!
Wow Chris, great explanation!
I never knew that and now that I do, I can see how useful this could be.
Thanks.
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.
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.
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!
Thanks for this info. I didn’t know this about css selectors.
Good old IE always causing problems, go figure.
Nice article… Great explanation!
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?
Really useful to remind, thanks.
Thank you for this, Chris.
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…
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″
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.
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.
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.
I thought #header.callout was a typo!
Thanks Chris – learnt something new today!
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.)
Great article, thanks for the info.
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}
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;}
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>
This is the right place to learn.
Thank you !
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.
Nice article, I think combining classes and ids is very useful.
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?
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
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.
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
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:
Desired DRY Example: (?)
Essentially what I want is to select multiple classes with multiple classes, but didn’t see that listed above.
Any ideas?
Good Stuff. A very helpful article for me.
Superb. Thanks for the expantion of id and class combination usage.