CSS Selectors: How to Use CSS Pseudo-Classes

Join the AI Workshop to learn more about AI and how it can be applied to web development. Next cohort February 1st, 2026

The AI-first Web Development BOOTCAMP cohort starts February 24th, 2026. 10 weeks of intensive training and hands-on projects.


Pseudo-classes are predefined keywords that select an element based on its state or position in the document.

They start with a single colon :.

Common Pseudo-Classes

Pseudo-classDescription
:linkUnvisited links
:visitedVisited links
:hoverElement being hovered
:activeElement being activated (clicked)
:focusElement with focus

Example: Styling links properly requires handling multiple states:

a {
  color: blue;
}

a:visited {
  color: purple;
}

a:hover {
  color: red;
}

a:active {
  color: orange;
}

Form States

Pseudo-classDescription
:enabledEnabled form elements
:disabledDisabled form elements
:checkedChecked inputs (checkbox, radio)
:requiredRequired form fields
:validValid form inputs
:invalidInvalid form inputs
input:disabled {
  background: #eee;
  cursor: not-allowed;
}

input:required {
  border-left: 3px solid red;
}

input:valid {
  border-color: green;
}

Structural Pseudo-Classes

Pseudo-classDescription
:first-childFirst child of its parent
:last-childLast child of its parent
:only-childElement with no siblings
:nth-child(n)Element at position n
:nth-last-child(n)Position n from the end
:first-of-typeFirst of its type among siblings
:last-of-typeLast of its type among siblings
li:first-child {
  font-weight: bold;
}

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

tr:nth-child(odd) {
  background: #f5f5f5;
}

The :nth-child() Selector

This powerful selector accepts various arguments:

/* Specific position */
li:nth-child(3) { }

/* Every odd element */
li:nth-child(odd) { }

/* Every even element */
li:nth-child(even) { }

/* Every 3rd element */
li:nth-child(3n) { }

/* First 3 elements */
li:nth-child(-n+3) { }

/* From 4th element onwards */
li:nth-child(n+4) { }

The :not() Selector

Excludes elements matching a selector:

/* All paragraphs except those with class "intro" */
p:not(.intro) {
  text-indent: 1em;
}

/* All inputs except submit buttons */
input:not([type="submit"]) {
  border: 1px solid #ccc;
}

Other Useful Pseudo-Classes

Pseudo-classDescription
:emptyElements with no children
:rootThe document root (html)
:targetElement matching URL fragment
/* Hide empty paragraphs */
p:empty {
  display: none;
}

/* Style the targeted section */
section:target {
  background: lightyellow;
}

Lessons in this unit:

0: Introduction
1: How to Use Basic CSS Selectors
2: How to Use CSS Attribute Selectors
3: ▶︎ How to Use CSS Pseudo-Classes
4: How to Use CSS Pseudo-Elements