A Feast of CSS3 Selectors for You

ChocolateChip uses the DOM’s built-in selector engine to get elements. Because this uses CSS3 selectors, you can use any combination of CSS3 selectors to get an element. This is especially important because a properly crafted CSS3 can help you avoid having to do other filtering tasks later to find the exact element that you wanted. By using a carefully constructed selector, you managed to pluck it out of the document with your first query and are ready to do something with it. Gone are the days of getting every li or p tag and checking them with JavaScript for certain conditions. Instead you can define you selector in such a way that you get a collection of the desired nodes from the start.

The W3C has a list of all the selectors that are available to use. At some point you want to read through the document carefully to fully understand how these selectors work. The barebones list is as follows:

Pattern Meaning Described in section
* any element Universal selector
E an element of type E Type selector
E[foo] an E element with a “foo” attribute Attribute selectors
E[foo=”bar”] an E element whose “foo” attribute value is exactly equal to “bar” Attribute selectors
E[foo~=”bar”] an E element whose “foo” attribute value is a list of
whitespace-separated values, one of which is exactly equal to “bar”
Attribute selectors
E[foo^=”bar”] an E element whose “foo” attribute value begins
exactly with the string “bar”
Attribute selectors
E[foo$=”bar”] an E element whose “foo” attribute value ends exactly
with the string “bar”
Attribute selectors
E[foo*=”bar”] an E element whose “foo” attribute value contains the
substring “bar”
Attribute selectors
E[foo|=”en”] an E element whose “foo” attribute has a
hyphen-separated list of values beginning (from the left) with “en”
Attribute selectors
E:root an E element, root of the document Structural pseudo-classes
E:nth-child(n) an E element, the n-th child of its parent Structural pseudo-classes
E:nth-last-child(n) an E element, the n-th child of its parent, counting
from the last one
Structural pseudo-classes
E:nth-of-type(n) an E element, the n-th sibling of its type Structural pseudo-classes
E:nth-last-of-type(n) an E element, the n-th sibling of its type, counting
from the last one
Structural pseudo-classes
E:first-child an E element, first child of its parent Structural pseudo-classes
E:last-child an E element, last child of its parent Structural pseudo-classes
E:first-of-type an E element, first sibling of its type Structural pseudo-classes
E:last-of-type an E element, last sibling of its type Structural pseudo-classes
E:only-child an E element, only child of its parent Structural pseudo-classes
E:only-of-type an E element, only sibling of its type Structural pseudo-classes
E:empty an E element that has no children (including text
nodes)
Structural pseudo-classes
E:link
E:visited
an E element being the source anchor of a hyperlink of
which the target is not yet visited (:link) or already visited
(:visited)
The link pseudo-classes
E:active
E:hover
E:focus
an E element during certain user actions The user action pseudo-classes and 2
E:target an E element being the target of the referring URI The target pseudo-class
E:lang(fr) an element of type E in language “fr” (the document
language specifies how language is determined)
The :lang() pseudo-class
E:enabled
E:disabled
a user interface element E which is enabled or
disabled
The UI element states pseudo-classes
E:checked a user interface element E which is
checked (for instance a radio-button or checkbox)
The UI element states pseudo-classes
E::first-line the first formatted line of an E element The ::first-line pseudo-element
E::first-letter the first formatted letter of an E element The ::first-letter pseudo-element
E::before generated content before an E element The ::before pseudo-element
E::after generated content after an E element The ::after pseudo-element
E.warning an E element whose class is “warning” (the document
language specifies how class is determined).
Class selectors
E#myid an E element with ID equal to “myid”. ID selectors
E:not(s) an E element that does not match simple selector s Negation pseudo-class
E F an F element descendant of an E element Descendant combinator
E > F an F element child of an E element Child combinator
E + F an F element immediately preceded by an E element Adjacent sibling combinator
E ~ F an F element preceded by an E element General sibling combinator

Out of the above selectors, the attribute selectors and the structural pseudo-classes offer you a whole lot of power in selecting otherwise difficult to define elements. You can get elements according to their attributes or the values of their attributes. You can get elements based on their relation to their siblings. You can even get an element based on whether it’s empty or not or by excluding elements of a certain type.

OK, time for some practical examples. One of the most common visual styling needs is zebra striping of rows or list. With CSS3 selectors this is easy. You have several ways to do this:

li:nth-of-type(even) – all even list items
li:nth-of-type(odd) – all odd list items
li:nth-of-type(10) – the 10th list item

Similarly, to we can use the nth-child selector to get the children of an element using the same notation. Here we’re going to to define a repeating set of four paragraphs. The first selector targets the first paragraph in that set, etc.

section:nth-child(4n+1) – first paragraph out of a set of four
section:nth-child(4n+2) – second paragraph out of a set of four
section:nth-child(4n+3) – third paragraph out of a set of four
section:nth-child(4n+4) – fourth paragraph out of a set of four

To get the 9th child out of a repeating set of 10, you can use this:
section:nth-child(10n-1) – would get 9th, 19th, 29th, 39th, etc.

As I mentioned, you can also get an element based on whether it’s empty, or you can exclude all elements of a particular type.

p:empty – a paragraph with no child nodes
:not(p) – all nodes except those of type “p”
p:not(p:empty) – all p tags except those that are empty
p:not(p[class]) – all p tags that do not have a class attribute.

From the above examples it should be clear the value of creating efficient selectors when you need to access elements in a document. Constructing a proper selector can eliminate the need for post filtering with JavaScript. This in turn will make your app faster and more responsive for the user.

Difference Between :first-child and :first-of-type

<section>
    <p>The first paragraph</p>
    <div>The first div</div>
    <div>The last div</div>
    <p>The last paragraph</p>
</section>

One last thing, you should be aware of the difference between :first-child and :first-of-type. If you look at the above markup you’ll see there are several paragraph tags and divs. You might think that you could use $("div:first-child") to get the first div. You’d be wrong. In the above code the first div is not the first child, it’s the second child. As such you would not get anything. To get the first div you’d need to use $("div:first-of-type). But if you really wanted the first child, regardless of what type of tag it is, you could use $("section").first() or $("section").firstElementChild. The same would apply when getting the last div or the last child in the above example. $("div:last-child") would not return the last div. $("div:last-of-type") would. To get the last child regardless of the tag, you could use $("section").last() or $("section").lastElementChild.

Advertisements