CSS Selectors: Just the Tricky Bits

by on 19th August 2011 with 34 Comments

div > p + div[id*='header'] – If you saw this jumbled mess of selectors in someone’s CSS, could you decipher it?

If not, then you’ll want to read this primer on funky CSS selectors that you should know!

A Flawed Education

Like many self-taught CSS guys, my education was cobbled together from a million different sources. I read articles, followed tutorials and experimented until my head hurt to get to a point where I could bust out a complex layout and achieve the styling that I want without too much trouble.

However, over time I slowly started to realize that I lacked a proper understanding of one of the most basic, essential elements to working with CSS: selectors. Sure, I knew how to target a class, ID or link, but I would often see snippets of code with selectors that seemed completely foreign to me.

After writing these confusing coding practices off for so long I decided to really sit down and learn about CSS selectors. It not only changed the way I code, it has drastically helped me interpret and learn from CSS that others write.

I am certainly not the first to write about CSS selectors and this article will by no means add anything revolutionary to the discussion. But if you’re like me, a self-taught coder with a mottled education, then this could just be the article that clarifies some of your biggest confusions when you stare in wonder at the cryptic code of others.

Meet The Family

Before you learn about complex CSS selectors. You need to understand a few things about HTML hierarchy. You’ve heard these terms tossed around before but it’s time to really think about them and make sure you grasp how they work.

The way we explain and refer to the structure of an HTML document is by using the metaphor of a family tree. There are parents, children, siblings, descendants and ancestors. To see what each means, let’s use the simple code below.

Wake Up Neo.

Follow the white rabbit.

Our div contains two paragraph elements and an anchor. All of these are descendants of the div, which occupies the root position in this instance. A child is a direct descendant of a parent. So in the example above, both paragraphs are children of the div but the anchor is not. Instead, it is a child of the second paragraph.

Similarly, if we go back up the tree, the div has a differing relationship to the items. The div is the parent of the paragraph tags but an ancestor of the anchor tag.

The final relationship is that of the siblings, also known as adjacent siblings. Just like in your family, siblings share a parent. So in the example above, the two paragraphs are siblings because the parent of both elements is the div. The anchor has no siblings because it is the paragraph’s only child.

Got That?

The family metaphor can get really confusing, but only if you over-think it. The terminology is fairly intuitive and if you think about the literal meaning of the word, you can pretty much guess what it means in HTML terms.

Just in case you still need a little more clarification, let’s rewrite the example above with content that explains the hierarchy of each element.

Child of the div above, sibling to the paragraph below.

Child of the div above, sibling to the paragraph above and parent to the anchor. Child of the paragraph, sibling of none and descendant of the div..

The Child Selector

Now that we understand how HTML works, we can start our discussion of CSS selectors, which leverage this system. Armed with our knowledge of what an HTML child really is, we can look at the CSS child selector.

The child selector is represented by the greater than symbol: “>”. You’ve seen this in CSS before but may or may not really understand how it works.

#someDiv > p {
    color: blue;
}

This statement takes the paragraph tags that are children of the div and turns them blue. Note that it only works for the children of that div, not necessarily all of the descendants. Let’s explore this further with the following example.

First paragraph with a link.

Second paragraph

screenshot

Let’s say for some horrible reason we wanted to change that link color to yellow. Obviously, we could target the link any number of ways, but we’re trying to learn about the child selector so go with me. Let’s see what happens if we implement this CSS:

div > a {
    color: yellow;
}

screenshot

Whoops, that didn’t change anything! That’s because the link is not a child of the div, it’s a child of the paragraph. So if we change that code to target any anchors that are children of paragraphs, we achieve our goal.

p > a {
    color: yellow;
}

screenshot

Order

Now that you understand how the child selector works, keep in mind that, as with all CSS, the order makes a big difference. To illustrate this, let’s start with this basic HTML structure:

First paragraph

Second paragraph

Third paragraph

Now let’s consider the following two CSS snippets. They look similar, but are very different!

#example3 p {
    color: red
}

#example3 > p {
    color: blue
}

#example3 > p {
    color: blue
}

#example3 p {
    color: red
}

The first snippet, makes all of the paragraphs to red, then changes only the children of the root div to blue.

screenshot

The second snippet does the opposite, it initially targets the first div’s child paragraphs and turns them to blue but then changes all of the paragraphs to red. This of course results in three red paragraphs.

screenshot

The second example breaks an important rule in CSS: go from general to specific, not the other way around. Since we started with a specific selector setup that targeted only two paragraphs and then moved to a general selector that targeted all of the paragraphs, the second completely overruled the first!

Chaining

If you really want to go nuts, you can chain child selectors together. In the following example, I first targeted any children paragraphs of the example3 div and changed them to blue, then I targeted any paragraphs that were the children of divs that were also children of another div and changed those to red.

First paragraph

Second paragraph

Third paragraph

#example3 > p {
    color: blue;
}

div > div > p {
    color: red;
}

screenshot

The Adjacent Sibling Selector

With child selectors all squared away we need to learn how to target siblings. The adjacent sibling selector is represented by the plus symbol: “+”. With it, we can target any element that is a sibling of any other element. Here’s an example:

First paragraph

Second paragraph

Third paragraph

Fourth paragraph

p + p {
    color: red;
}

screenshot

In our CSS, we used the adjacent sibling selector, which changed the second and third paragraph to red. This is very tricky isn’t it? instinctively, we would expect the first paragraph to be red as well. After all, the first paragraph is on the same level of the tree as the next two and has siblings. However, this selector only applies to elements that are preceded by something else. In this instance, only those paragraphs preceded directly by a sibling paragraph will be targeted. The first paragraph in the list is preceded by the div, so it isn’t changed.

With this in mind, the following code would change the background of the nested div to gray because it is indeed preceded by a paragraph.

p + div {
    background: gray;
}

Further Chaining

Just as with child selectors, you can chain adjacent sibling selectors. The system works exactly the same as before. You can also combine the two for an added layer of complication. Here’s where our CSS really starts to look strange.

First paragraph

Second paragraph

Third paragraph

Fourth paragraph

div > p + p {
    color: red;
}

screenshot

In this example, we targeted paragraphs that were children of divs that were also preceded directly by another paragraph.

The Almighty Asterisk

The final piece of confusing CSS that I want to go over is the worst yet: the asterisk. Did you know that, depending on the context, the asterisk can refer two completely different things?

Universal Selector

The first example of an asterisk in CSS is the one you’re probably the most familiar with: the universal selector. True to its name, this selector targets any and every element on the page. We typically see it used in CSS resets. The following resets the padding and margin on every element.

* {margin: 0; padding: 0;}

You can take this further and achieve some really interesting results. For instance, the following turns every element inside a div red, this includes items like links that have a default color set to something else and wouldn’t be affected by simply targeting the div.

#someDiv * {
    color: red;
}

Further, this snippet targets grandchild paragraphs of the div, but not direct child paragraphs.

div * p {
    color: red;
}

You can take this as far as you want, the following targets the great grandchildren of the div. You can see this chaining method used frequently in CSS debugging tricks.

div * * p {
    color: red;
}

Arbitrary Substring Attribute Value Selector

Now with CSS3, the asterisk can also be used to implement the arbitrary substring attribute value selector, you can pull that title out when talking to other developers if you’re trying to look smart.

The following code targets any div with the word “section” in the title. It can be “section3″ or “section-Four”, it doesn’t matter, as long as it contains the indicated string, the subsequent styles apply.

div[id*='section'] {color: red;}

This code would apply to all of the divs in this HTML:

Attribute Selectors

That last curve ball that I threw you was an example of an attribute selector. In CSS3, attribute selectors are so complicated that they merit their own article! Fortunately for you, we have a piece on that very topic.

CSS Attribute Selectors: How and Why You Should Be Using Them

If you’re a nerd like me, this is a really fascinating topic. It’s amazing to see all of the selector tools that you have at your disposal.

Pseudo Class Selectors

This is yet another selector topic that you should familiarize yourself with, and once again it really does merit a thorough inspection of the topic. As with just about every CSS topic known to man, CSS-Tricks has you covered.

Meet the Pseudo Class Selectors

Conclusion

With CSS, there’s almost always more than one way to target something. In fact, there’s often half a dozen ways. For any of the examples above, you can probably name a quicker way to target what we were shooting for, but as you familiarize yourself with the DOM, these selectors really do start to come in handy.

Even if you never find yourself in need of them, it’s vitally important to understand them because you will see them projects that you collaborate on, frameworks that you download, tutorials that you read and any other place that you regularly find code. Understanding HTML element relationships and their corresponding CSS selectors can only make you a better coder!

Comments & Discussion

34 Comments

  • http://sumtips.com Renji

    Wow.. those are tricky! And now I have something to learn this boring weekend. Thanks!

  • http://www.eastdevonit.co.uk Dan – Web Designer

    Great post, thanks. You’ve explained these really well!

    I just need to find some reason to use them now!!

  • http://www.miketheindian.com Mikey

    Woah, the “Arbitrary Substring Attribute Value Selector” just blew my mind. Never knew that was possible.

  • aabir

    These are very useful and smart.
    Thanks.

  • http://www.united1in.com Vikram

    Thank you for this post, it will come handy in many situation. Waiting for more on CSS3 info

  • http://www.alexnovelli.com Alex Novelli

    Thank you so much! Weeks I’ve been looking for something to explain about these selectors.

  • Megan

    I learned the same way as you. This was really great to read. I had at least one “d’oh!” moment :) Thanks for your time!

  • John S.

    Thanks for the great education!

    I’m wondering: what is the general consensus about how to get all of this CSS goodness to play nice even in [gasp] IE6? There seem to be a lot of shims/hacks out there, but I’m curious to know what people’s preferences are.

  • Char

    Awesome article, thanks! :) Very helpful.

  • http://www.slideaway.ca jamEs

    John S: Stop supporting IE6. I work for a pretty big company with thousands of clients and we discontinued IE6 support over a year and a half ago. I have not heard one single complaint about IE6 rendering in my time with the company. For my freelance company I now have a clause in all my contracts stating no IE6 support. As much as you can state that you wish IE6 would go away, you’re enabling the users by continuing to support their browser choice.

  • Philippe Alves

    This is really what I was looking for a long time ago! I mean, WOW! Indeed, learning CSS by yourself, you can pass by important and needed tricks.

  • Suyoj

    Thank you very much for sharing beautiful knowledge in CSS selector.

  • http://www.bigswebdesign.co.uk/ Stewart

    Nice post, like the comment by James. eveyone should stop supporting IE6 :-}

  • http://www.webdesigncreare.co.uk Kim Ruddock

    Great explanation of additional CSS selectors to use in site development. These selectors can save a lot of extra coding and creation of unnecessary styles. It was interesting to read about using the * selector as more than just a reset style. The substring attribute value selector is an interesting one as long as the styles are still named in ways that are understandable to others.

  • http://alchemyindesign.com Leban Hyde

    Nice post! Also a fellow self-taught coder. We need all the help we can get ;-)

    You can also check out the CSS Cookbook (O’Reilly). It addresses complex selectors along with some other nifty tricks and “hacks”. You still need to understand the DOM, but it expedites the curve a bit.

    Cheers!

  • http://www.brandify.co.uk/ Peter

    I’ve also dropped support for IE6 with the exception of the really big sites that still have several thousand IE6 users, although their experience is more restricted.

    Great article btw, I never knew about the + selector!

  • http://bsides.com.br bsides

    Great article, very informative. May I reproduce it in my own language (portuguese)? Of course, keeping the credits :)

    Keep up the good work!

  • http://Www.matthewleichty.com Matthew

    Of course, our organization can’t use any of this because we still support IE6.

  • http://obtuze.wordpress.com Arijit

    Thanks for this! Great read…

  • Katie

    If only these were supported by all browsers. I tend to lean on jQuery when I can’t directly select an item, but these tips are so handy. I had no idea CSS had so much more to it. Great article! I learned something new today.

  • George Katsanos

    Thanks Joshua, great article. One comment thought: Google (in Page Speed guidelines*) advises to avoid some of these selectors to improve browser rendering performance.

    *http://code.google.com/speed/page-speed/docs/rendering.html

  • Bill

    Great article! I generally feel I know my way around CSS pretty well, but this article really provided a lot of insight. Thanks!

  • http://karlmac.com karl

    new to these css selectors. great stuff. thanks for sharing!

  • http://texxsmith.com Texx

    Three reasons to use selectors as little as possible.

    This article was well written and I can tell a lot of work went into it. However you missed a main point – WHY uses selectors at all? I’m glad you didn’t recommend using them, but you didn’t warn people away either. #2 below can have devastating consequences to a web app.

    Here’s why you shouldn’t:

    1 – Breaks the rules – Selectors are based on the id
    attribute, each of which is supposed to be unique and not repeated. This kinda defeats the purpose of using CSS if your style unique elements regularly.
    2- It messes up your programmer. He needs to use those id and name attributes for other things. He’s expensive. don’t waste his time.
    3- It’s already hard enough for others to read your CSS without finding yet another place to set the style rules for elements. Don’t be a player hater and make it even harder for someone to find where you’ve applied a style, or part of the styles to an element.

    Three reasons

  • allen

    This was a great article, but I’m confused about the purpose of the Arbitrary Substring Attribute Value Selectors. Doesn’t this copy the functionality of classes? Can anyone describe a time when it would be better to use ASAVS over classes?

  • http://lamiakaren.com Lamia

    Concise and thorough. CSS is quite straightforward – but there are so many bad examples on the web that I start to question my understanding. Thank you for establishing a solid foundation and THEN adding all the fun stuff.

  • http://www.angrybirdsrio.biz Viet Designer

    Great article, I fully agree and I think you are doing a goob job in convincing CSS is the way to go.
    From your post I’ve done a quick company. Recently I completely re-engineered the frontend of this website: Angry birds rio

  • http://www.junyuetrade.com NikeJordans

    I got more useful information on this blog.. Thanks to sharing the useful information.

  • ercan

    Your blog is wonderful, I like it very much, thank you!! boyaci Thank you to expect this site

  • http://www.android14.com android phone

    thank you, I will always practice

  • AntoxaGray

    One selector that I miss is the parent selector. I can’t understand reason why they decided not to include it, I have to use jQuery for that instead.

  • http://jonnyt.me Jon Tarbuck

    These selectors are great, have helped me out of a few tricky situations, although I’ve ended up with some pretty crazy ones.

  • http://baguioads.ph/ Gary Dapogi from Baguio Ads

    I’ve read this before and forgot to bookmark it. Until now again that I needed to read and refresh my memory, I did again a research and lucky enough, I’ve found again this article.

    I’m looking for this article over at css-trics, but I think Cris does not have this one.

  • Jessi Hance

    The place where these come in really handy is in styling content that you have no control over, and which doesn’t have the classes or ids you’d need to do it otherwise. Think user-generated content, or content generated by third-party CMS plugins.

Subscribe
Membership
About the Author