Learn everything you need to know about the Pseudo Classes in CSS

Before you check out those cool features, take a step back and inspect the CSS basics through my CSS Basic Selector post.

In this article we will take a look of the CSS Pseudo Classes

Pseudo Classes

A Pseudo-class is a keyword added to a CSS selector that specifies a special state of the selected element(s).

Note: This state is not contained in the HTML document tree

Pseudo-classes allow us to apply a style to an element in relation to external factors like the history of the navigator (:visited), the status of its content (:checked), or the position of the mouse (:hover).

It’s very common to use the pseudo-class :hover, for example we can use it to change a button’s style when the user’s pointer hovers over it, like the background.

<button class="btn">call to action</button>
.btn {
  padding: 20px;
  background: #ed3330;
  color: #fff;
  border-radius: 5px;
  border: none;
  transition: background 300ms ease-in-out;

.btn:hover {
  background: #f6b93b;

The Pseude-classes always start with a single colon : and like the regular classes, you can chain together as many pseudo-classes as you want in a selector.

They can be used as part of any selector, and they are very useful to change the styles of an element based on his state, as we already say, the relation of the element with external factors, they can be very handy in many cases, for example to style active or visited links, change the style on hover, focus, or target the first child, or odd rows.

These are the most popular pseudo classes you will likely use:

:activean element being activated by the user (e.g. clicked). Mostly used on links or buttons
:checkeda checkbox, option or radio input types that are enabled
:defaultthe default in a set of choices (like, option in a select or radio buttons)
:disabledan element disabled (opposite to :enabled)
:emptyan element with no children
:enabledan element that’s enabled (opposite to :disabled)
:first-childthe first child of a group of siblings
:first-of-typethe first element of its type among a group of sibling elements
:focusthe element with focus
:foucs-withinan element that is itself matched by the :focus or has a descendant that is matched by :focus
:hoveran element hovered with the mouse
:invalidform elements whose contents fail to validate (opposite to :valid)
:last-childthe last child of a group of siblings
:last-of-typethe last element of its type among a group of sibling elements
:linka link that’s not been visited
:not()any element not matching the selector passed. E.g. :not(span)
:nth-child()an element matching the specified position
:nth-last-child()an element matching the specific position, starting from the end
:only-childan element without any siblings
:read-onlyan element that is not editable by the user
:requireda form element with the required attribute set
:rootrepresents the html element. It’s like targeting html. Useful in CSS Variables.
:targetthe element matching the current URL fragment (for inner navigation in the page)
:validform elements that validated client-side successfully (opposite to :invalid)
:visiteda link that’s been visited

You can find more information about the pseudo-classes at MDN Pseudo-classes

Now let’s do some examples.

Very often. You want to style a link, so you create a CSS rule to target the a element:

a {
  color: green;

Things seem to work fine, until you click one link. The link goes back to the predefined color blue when you click it. Then when you open the link and go back to the page, now the link is blue.

Why does that happen?

Because the link when clicked changes state, and goes in the :active state. And when it’s been visited, it is in the :visited state. Forever, until the user clears the browsing history.

So, to correctly make the link yellow across all states, you need to write

a:active {
  color: green;

For one more complex example lets use :nth-child(). It can be used to target odd or even children with :nth-child(odd) and :nth-child(even).

It is commonly used in lists to color odd lines differently from even lines:

ul:nth-child(odd) {
  color: #fff;
	background: #333;

You can also use it to target the first 3 children of an element with :nth-child(-n+3). Or you can style 1 in every 5 elements with :nth-child(5n).