CSS3 Selectors, Pseudo-classes and Pseudo-elements

As CSS4 starts to take shape, CSS3 talk has become less exciting after only a year since its release date. Not only that, but thanks to the lack of browser support CSS3 came with, quite a few of us have neglected it for the most part and some of us never even spent the time trying to learn its new features. So, before we move on to CSS4 let’s make sure we know everything that CSS3 is capable of.

I recently attended the Future Insights Live Conference (recap here) in Las Vegas and the one session that satisfied my craving for new knowledge the most was the one about CSS3 Selectors with Estelle Weyl. CSS keeps getting better and more versatile, but even though all its new features are impressive I still think there’s plenty of room for improvement. And the unanswered question is: should we focus on support or optimization? I’m sure we will get there eventually, it can only get better from here. But as long as you don’t mind skipping (cough) IE8 (cough) and below for now, then CSS3 selectors are still worth mentioning; they do make our front-end job a lot easier, so here we go.

And before we start, for the sake of keeping things short and simple, I will only list the selectors, pseudo-classes and pseudo-elements here and give a few short explanations. Stay tuned for a more in-depth tutorial on my next blog post.


Basic Selectors:

IDs: #my-id

Classes: .my-class

Tags: <h1>, <p>, <li>, etc

Relation Selectors:

ul li
Descendant selector: Matches all nested <li>s.

ol > li
Child selector: Matches <li>s in <ol> but not nested ones.

li.my-class + li
Matches only the adjacent sibling.

li.my-class ~ li
General sibling selector: Matches later siblings but not nested one. New in IE7+.

Attribute Selectors:

img[alt] {}
Selects only images with an ‘alt’ attribute

Selects any element in the form with the ‘type’ attribute. IE7 supports non-empty attributes

Older Attribute Selectors:

E[attr] Selects element E that has the attribute attr with any value.

E[attr=”val”] Selects element E that has the attribute attr with the exact, case-sensitive (if attribute is case sensitve) value val.

E[attr|=val] Selects element E whose attribute attr has a value val or begins with val– (“val” plus “-“)

E[attr~=val] Selects element E whose attribute attr has within its value the space separated full word val.

CSS3 Attribute Selectors:

E[attr^=val] Selects element E whose attribute attr starts with the value val.

E[attr$=val] Selects element E whose attribute attr ends in val .

E[attr*=val] Selects element E whose attribute attr matches val anywhere within the attribute. Similar to E[attr~=val] above, except the val can be part of a word.

And you can join multiple attributes!


They select elements that already exist

UI Pseudo-classes:

Based on current state of UI:




Form related UI pseudo-classes:




: optional


: out-of-range




Structural Selectors:

They’re based on their relationship to other elements in the DOM, but you’ve got to be careful with these, because they will update dynamically if page updates. They’re great for reducing extra markup, classes and IDs









: only-child()

: only-of-type()




Nth pseudo-classes:

Use these to be more specific







And you can also join these:

Negation pseudo-classes:


Empty pseudo-class:

If all the content is commented out, it will still be recognized as empty.

Other pseudo-classes:









Pseudo Elements:

They create fake elements you can style






For IE compatibility use only a single colon.

And there you go folks, I will be sitting here wondering if all of this information boggled your mind the way it did mine (you can let me know in the comment section below). CSS is still to this day the most reliable element styling method and it certainly has tons of potential to be even better. I also believe CSS is like art, where the utensil does not matter but only the artist. If you are interested in learning or showing off your CSS3/HTML5 skills I recommend taking a look at the new version of CSS Zen Garden!


“We need native CSS media queries at the element/component/widget
level, not just the viewport. Make it so, internetz.”

-Nicolas Gallagher, via Twitter