← Back to Chapters

CSS Pseudo-classes

? CSS Pseudo-classes

✨ Quick Overview

CSS pseudo-classes let you style elements based on their state (like hover or focus) or position (like first child) without adding extra classes or JavaScript.

Think of them as “conditional styles” that are applied only when something special is true about an element.

? Key Concepts

  • :hover — when the mouse pointer is over an element.
  • :focus — when an element (usually input) is focused via click or keyboard.
  • :first-child — targets the first child of a parent.
  • :nth-child(n) — targets elements based on their index (e.g., odd/even rows).
  • :disabled — matches disabled form controls.

? Syntax & Theory

Basic syntax for a pseudo-class:

? View General Syntax
/* Basic pseudo-class syntax pattern */
selector:pseudo-class {
  property: value;
}

You attach the pseudo-class after the selector using a colon (e.g., a:hover, input:focus).

?️ :hover

:hover applies styles when the mouse pointer is over an element. Commonly used for buttons, links, and interactive cards.

? View :hover Example
/* Change link color and underline only on hover */
a:hover {
  color: #dc3545;
  text-decoration: underline;
}

? Live Output (Conceptual)

Move your mouse over the second link to see the hover effect:

Normal Link Hover me!

Note In real CSS, the second link would change style when hovered.

? :focus

:focus targets an element when it gains focus via mouse click or keyboard (Tab key). It is very important for accessibility.

? View :focus Example
/* Highlight input when user focuses on it */
input:focus {
  border-color: #28a745;
  outline: none;
  box-shadow: 0 0 0 2px rgba(40, 167, 69, 0.2);
}

⌨️ Live Output (Conceptual)

Click or press Tab to focus this field:

When focused, the border turns yellow and gets a soft glow.

? :first-child

:first-child selects the first child of its parent. Great for styling the first item in a list or the first paragraph in a section.

? View :first-child Example
/* Make the first list item stand out */
li:first-child {
  font-weight: bold;
  color: #007bff;
}

? Live Output (Conceptual)

The first list item is styled differently:

  • First item
  • Second item
  • Third item

? :nth-child(n)

:nth-child(n) styles elements based on their position. You can use numbers, formulas like 2n, or keywords like odd and even.

? View :nth-child(odd) Example
/* Color every odd list item (1st, 3rd, 5th, ...) */
li:nth-child(odd) {
  background-color: #f0f8ff;
}

? Live Output (Conceptual)

Odd items have a light background:

  • Item 1
  • Item 2
  • Item 3
  • Item 4

? :disabled

:disabled selects disabled form elements like inputs and buttons. Use it to show that a control cannot be used.

? View :disabled Example
/* Style disabled buttons to look inactive */
button:disabled {
  background-color: #cccccc;
  color: #6b7280;
  cursor: not-allowed;
}

? Live Output (Conceptual)

Disabled vs active button:

? Combined Pseudo-class Example

You can combine multiple pseudo-classes to create rich interactions, such as different styles on hover, focus, and disabled states.

? View Combined Button Styles
/* Button styles using multiple pseudo-classes */
.button {
  padding: 0.6rem 1.2rem;
  border-radius: 999px;
  border: none;
  background-color: #2563eb;
  color: #ffffff;
}

.button:hover {
  background-color: #1d4ed8;
}

.button:focus {
  outline: 2px solid #93c5fd;
  outline-offset: 2px;
}

.button:disabled {
  background-color: #9ca3af;
  cursor: not-allowed;
}

? Live Output (Conceptual)

Imagine a pill-shaped button that:

  • Gets darker on :hover.
  • Shows an outline on :focus.
  • Turns gray and unclickable when :disabled.

? Tips & Best Practices

  • Always keep :focus styles visible for keyboard and screen-reader users.
  • Use :hover to give feedback, but don’t rely on it alone (touch screens have no hover).
  • Use :first-child and :nth-child() to style table rows or list items without extra classes.
  • Make :disabled elements visually different so users know they can’t interact.
  • Combine pseudo-classes to create smooth, consistent UI states.

? Try It Yourself

  1. Create a navigation bar where links change background color on :hover and get an outline on :focus.
  2. Style a list of tasks so that :first-child is bold and all :nth-child(even) items have a light background.
  3. Build a form where the “Submit” button is :disabled until all required inputs are filled (you can later enable it with JavaScript).
  4. Experiment with other pseudo-classes like :active and :visited for links and buttons.