Learn5 Useful CSS Selectors

   
Avatar

Guil Hernandez
writes on January 10, 2013

Besides the usual type, descendant, class and ID selectors, CSS offers several pseudo-class and pseudo-element selectors that allow us to target HTML elements based on their positions in the document –– some even target virtual elements and generate content from the CSS. In this article, we’ll take a look at 5 handy CSS selectors to keep in mind when styling your web pages and applications.

:first-child and :last-child

The :first-child and :last-child structural pseudo-classes let us select the first or last child of a parent element.

For example, if we only need to select the first list item of an unordered list, we can use the :first-child pseudo-class:

li:first-child {
   border-top: none;
   font-weight: bold;
}

Similar to :first-child, the :last-child pseudo-class selects an element that is the last child of its parent element.

li:last-child {
   border-bottom: none;
}

:nth-child

:nth-child is one of the most useful structural pseudo-classes available; it lets us select elements based on their positions within a parent element.

:nth-child uses a function-like syntax that allows an argument to be passed in between parentheses –– inside the parentheses is where we declare how the elements will be selected.

One of the arguments that can be accepted is the keyword odd or even, which can be used to select every other child element. The following rule will only target the even-numbered list items.

li:nth-child(even) {
   color: white;
   background-color: black;
}

The keyword “even” is useful for selecting every other item in a list.

Another argument we can use in between the parentheses is an integer. For example, this rule will only select the third list item inside the parent ul.

li:nth-child(3) {
   background-color: tomato;
}

What makes arguments really powerful is when using expressions to select a particular combination of child elements. Our basic expression syntax looks something like this:

:nth-child(an+b)

The values a and b are always represented by a number, and the n value does not change. The b value is an offset value that determines which element is selected first. The a value determines the cycle of elements to select after the first one has been selected. The n value doesn’t change — think of n as a counter that starts at zero and indicates the a value to the browser.

li:nth-child(2n+3)

In the expression above, the third list item will be the first one selected in our list (the b value) ignoring all sibling list items that precede it, then every 2nd list item (determined by the a value) until there are no more list items to select.

An expression like the one below will select the 5th list item first, then all list items before it (indicated by the -n value).

li:nth-child(-n+5)

Sometimes it may be beneficial—and practical—to use a class instead of an overly complex rule, as some can be difficult to maintain over time. For example, say you have a rule like the following:

div:nth-last-of-type(2n+10) {  
   background: yellow;
   color: red;
}

Think of the developer (or yourself) that has to manage this code a few weeks or months down the road. This is when we’re better off using a simple class such as:

.warning {  
   background: yellow;
   color: red;
}

:nth-of-type

:nth-of-type selects an element based on its position within a parent’s list of children of the same type specified. This is a more flexible and useful selector if you want to be sure you’re selecting the same type of element no matter where it is inside the parent element or what other elements appear before it.

For example, if we only want to select the fourth image on the page, we need to first specify the img element, then :nth-of-type followed by the argument.

img:nth-of-type(4) {
   border-color: red;
}

:target

The :target pseudo-class allows us to style elements based on the URI –– it selects the element that shares the same ID as the URI once it’s targeted by the browser. A link with a fragment identifier will link to an element within the document, known as the target element.

For example, say our HTML had the following elements:

<a href="#intro">Introduction</a>
<a href="#conclusion">Conclusion</a>

...

<div id="intro">...</div>
<div id="conclusion">...</div>

Our CSS rule:

:target {
   border: 5px solid blue;
}

The browser will target the div with the corresponding ID and apply the :target selector styles once the link is clicked –– because when we click on a link that ends with a fragment identifier, that element we are pointing to becomes the target.

::before and ::after Pseudo-elements

Pseudo-elements let us target virtual elements that are not specified in the HTML. With the ::before and ::after pseudo-elements we can insert virtual elements before or after an element’s content that are visible to the user and are styleable in the CSS –– so we can actually add to our HTML from our CSS. This is called generated content.

::before

The ::before pseudo-element will insert content before the selected element. In order for this to work properly we must use the content property, otherwise we won’t be able to generate or insert any content. At the very least, it must contain empty quotes as its value.

.pdf::before {
   content: url(img/pdf.png);
   margin-right: 10px;
}

In the example above, a PDF icon was generated before the link’s content.

::after

The ::after pseudo-element works just like the ::before pseudo-element except that it inserts content after the selected element’s content.

An important thing to keep in mind is that the generated content is not exactly inserted before and after the targeted element as expected. It’s actually inserted as child content in relation to the element.

blockquote::before {
   content: "\275D";  /* unicode icon for opening mark */
   margin-right: 20px;
}
blockquote::after {
   content: "\275E"; /* unicode icon for closing mark */
   margin-left: 20px;
}

In this example, the opening quotation mark is actually inserted inside of the blockquote’s content box –– it’s inserted before the text and not before the actual blockquote element. With the ::after pseudo-element, the closing mark is inserted the same way, except that it’s appended to the content. I added a border around the blockquote so we can clearly see how this works:

Support

The selectors we covered have excellent support in the major browsers. Selectors like :target and :nth-child, however, are not supported in IE8 and below. But IE8 does support the one-colon syntax for the :before and :after pseudo-elements.

These are just a few of the many pseudo-classes and pseudo-element selectors available to us. For a full summary of all selectors and their syntax, take a look at the Selectors Level 3 Module spec: http://www.w3.org/TR/css3-selectors/#selectors.

GET STARTED NOW

Learning with Treehouse for only 30 minutes a day can teach you the skills needed to land the job that you've been dreaming about.

Get Started

8 Responses to “5 Useful CSS Selectors”

  1. Ashwini Karai on January 20, 2018 at 7:38 pm said:

    Undoubtedly, a super helpful compilation. Will come handy during my test automation adventures. Thanks, much!

  2. Guil,
    you’re the bomb!

    Following your CSS course these days.

    This article is a very helpful revisit.

  3. Great article.
    I trying the style same elements and I want to style every four child differently.
    I want child 1 to have some background color, child 2 different background color from 1,
    child 3 different background color from 1 and 2, child 4 different background color from 1 and 2 and 3

    Can I make this?
    I tried some codes but they did not work

    • Sure, you can use the described nth-child selector.
      .itemClass:first-child{ /*color for 1st item*/ } (same as .itemClass:nth-child(1) )
      .itemClass:nth-child(2){ /*color for 2nd item*/ }
      .itemClass:nth-child(3){ /*color for 3rd item*/ }
      .itemClass:nth-child(4){ /*color for 4th item*/ }

  4. Anytime I need anything, Treehouse always pops up. Maybe I should sign up…

  5. Ravinder Kumar on April 23, 2013 at 10:40 am said:

    Nice article, very useful to me.
    Best of luck for future….
    🙂

Leave a Reply

You must be logged in to post a comment.

man working on his laptop

Are you ready to start learning?

Learning with Treehouse for only 30 minutes a day can teach you the skills needed to land the job that you've been dreaming about.

Start a Free Trial
woman working on her laptop