Skip to content

CSS Pseudo-classes

CSS pseudo-classes are special keywords added to selectors to style elements based on their state, position, interaction, or condition. They are commonly used for hover effects, focus states, form validation, selected items, child selectors, and accessible interactive UI.

What Are CSS Pseudo-classes?

A CSS pseudo-class selects an element when it is in a specific state or matches a specific condition. Pseudo-classes start with a single colon :.

a:hover {
  color: #0d6efd;
}

input:focus {
  outline: 3px solid #111111;
}

In these examples, :hover styles a link when the user points to it, and :focus styles an input when it receives keyboard or mouse focus.

Why CSS Pseudo-classes Are Important

  • They create interactive states without JavaScript.
  • They improve usability for buttons, links, menus, and forms.
  • They support accessible keyboard focus states.
  • They help style selected, disabled, checked, and required controls.
  • They make lists, tables, cards, and grids easier to style.
  • They reduce extra class names in HTML.
  • They help build cleaner and more maintainable CSS.

CSS Pseudo-classes Cheatsheet

The following table explains commonly used CSS pseudo-classes and their purpose.

Pseudo-class Example Purpose
:hover a:hover Styles an element when the pointer is over it.
:focus input:focus Styles an element when it receives focus.
:focus-visible button:focus-visible Shows focus styles mainly for keyboard navigation.
:active button:active Styles an element while it is being activated.
:visited a:visited Styles links already visited by the user.
:first-child li:first-child Selects the first child element.
:last-child li:last-child Selects the last child element.
:nth-child() tr:nth-child(even) Selects elements based on their position.
:not() .card:not(.featured) Selects elements that do not match a selector.
:checked input:checked Selects checked radio buttons or checkboxes.
:disabled button:disabled Selects disabled form controls.
:required input:required Selects required form fields.
:valid input:valid Selects form inputs with valid values.
:invalid input:invalid Selects form inputs with invalid values.

CSS Pseudo-class Syntax

A pseudo-class is added after a selector using a single colon.

selector:pseudo-class {
  property: value;
}

Example:

.button:hover {
  background-color: #0b5ed7;
}

:hover Pseudo-class

The :hover pseudo-class applies when a user points to an element with a mouse or trackpad.

.card:hover {
  transform: translateY(-4px);
  box-shadow: 0 0.75rem 1.5rem rgba(0, 0, 0, 0.12);
}

Do not rely only on hover, because touch devices may not support hover behavior.

:focus Pseudo-class

The :focus pseudo-class applies when an element receives focus through keyboard navigation, mouse click, or script.

input:focus,
textarea:focus,
select:focus {
  outline: 3px solid #111111;
  outline-offset: 3px;
}

Focus styles are essential for keyboard accessibility.

:focus-visible Pseudo-class

The :focus-visible pseudo-class shows focus styles when the browser determines they are helpful, usually during keyboard navigation.

button:focus-visible,
a:focus-visible {
  outline: 3px solid #111111;
  outline-offset: 3px;
}

This is useful when you want clean mouse interactions while still supporting keyboard users.

:active Pseudo-class

The :active pseudo-class applies while an element is being activated, such as while pressing a button.

.button:active {
  transform: translateY(1px);
}

Child Pseudo-classes

Child pseudo-classes select elements based on their position inside a parent.

li:first-child {
  font-weight: 700;
}

li:last-child {
  margin-bottom: 0;
}

tr:nth-child(even) {
  background-color: #f8f9fa;
}

These are useful for lists, tables, cards, menus, and repeated UI components.

:nth-child() Pseudo-class

:nth-child() selects elements based on a pattern or position.

li:nth-child(2) {
  color: #0d6efd;
}

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

tr:nth-child(even) {
  background-color: #f8f9fa;
}

Common values include numbers, odd, even, and formulas like 3n.

:not() Pseudo-class

The :not() pseudo-class selects elements that do not match a selector.

.button:not(.button-primary) {
  background-color: #f8f9fa;
  color: #212529;
}

.card:not(:last-child) {
  margin-bottom: 1rem;
}

Use :not() to reduce extra utility classes and keep selectors expressive.

Form Pseudo-classes

Form pseudo-classes style inputs based on their state or validation status.

input:required {
  border-left: 4px solid #0d6efd;
}

input:valid {
  border-color: #198754;
}

input:invalid {
  border-color: #dc3545;
}

button:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

:checked Pseudo-class

The :checked pseudo-class selects checked checkboxes and radio buttons.

input[type="checkbox"]:checked + label {
  font-weight: 700;
  color: #0d6efd;
}

This is useful for custom checkboxes, selected filters, toggles, and option lists.

:disabled and :enabled Pseudo-classes

These pseudo-classes style form controls based on whether they can be used.

button:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

input:enabled {
  background-color: #ffffff;
}

:empty Pseudo-class

The :empty pseudo-class selects elements that have no children or text content.

.alert:empty {
  display: none;
}

This can help hide empty message containers or placeholder blocks.

:root Pseudo-class

The :root pseudo-class selects the root element of the document. It is commonly used for CSS custom properties.

:root {
  --color-primary: #0d6efd;
  --space-md: 1rem;
}

.button {
  background-color: var(--color-primary);
  padding: var(--space-md);
}

CSS Pseudo-classes and Accessibility

  • Always provide visible focus styles with :focus or :focus-visible.
  • Do not rely only on :hover because touch users may not experience it.
  • Keep disabled states visually clear.
  • Use validation pseudo-classes carefully so errors are understandable.
  • Make interactive states visible with more than color alone when possible.
  • Test keyboard navigation through links, buttons, forms, and menus.

CSS Pseudo-classes and SEO

CSS pseudo-classes do not directly create search rankings, but they improve usability, accessibility, interaction quality, form experience, and content presentation.

  • Better interactive states improve user experience.
  • Accessible focus styles support more users.
  • Readable hover and active states improve navigation.
  • Clean form states reduce user frustration.
  • Better UI quality can improve engagement and trust.

Common CSS Pseudo-class Mistakes

  • Removing outlines without providing replacement focus styles.
  • Relying only on :hover for important interactions.
  • Confusing pseudo-classes with pseudo-elements.
  • Using overly complex :nth-child() selectors that are hard to maintain.
  • Styling invalid fields before the user has interacted with the form.
  • Using :visited expecting full styling control.
  • Writing selectors that become too specific and hard to override.

CSS Pseudo-class Best Practices

  • Use :hover for optional pointer enhancements.
  • Use :focus-visible for keyboard-friendly focus styles.
  • Use :disabled to make unavailable controls obvious.
  • Use :checked for selected checkbox and radio states.
  • Use :nth-child() for repeated list and table patterns.
  • Use :not() to avoid unnecessary extra classes.
  • Keep selectors readable and easy to maintain.
  • Test interactive states with mouse, keyboard, touch, and screen readers.

Key Takeaways

  • CSS pseudo-classes select elements based on state, position, or condition.
  • Pseudo-classes use a single colon, such as :hover and :focus.
  • :hover, :focus, and :active style interactive states.
  • :first-child, :last-child, and :nth-child() select elements by position.
  • :checked, :disabled, :valid, and :invalid are useful for forms.
  • Good pseudo-class usage improves accessibility, usability, and maintainable CSS.

Pro Tip

For accessible interactions, pair :hover styles with :focus-visible styles so both mouse users and keyboard users get a clear interactive experience.