CSS Lesson 23 – Pseudo-Classes | Dataplexa
LESSON 23

Pseudo-Classes

Style elements based on their state and position using interactive CSS selectors

Pseudo-classes are special selectors that target elements based on their state or position — like when a button is hovered over, when a link has been visited, or when an input field is focused. Think of them as CSS detectives that watch for specific conditions and apply styles when those conditions are met. The WanderLust team wants to add interactive hover effects to their navigation buttons, style form inputs when users click into them, and highlight the first destination card differently from the rest. Pseudo-classes make all of this possible without any JavaScript.

Understanding Pseudo-Class Syntax

Pseudo-classes always start with a single colon (`:`) followed by the state name. You attach them to regular selectors to create conditional styling rules. When the condition is met, the styles apply automatically.
selector
:pseudo-class
{ styles }
Element to target
State condition
Styles when active
/* Style navigation links when users hover over them */
.nav-link:hover {
  background: #0ea5e9; /* WanderLust sky blue background */
  color: #ffffff; /* White text for contrast */
  transform: translateY(-2px); /* Subtle lift effect */
}
localhost/index.html

What just happened?

The :hover pseudo-class detected when your mouse moved over each link and applied the blue background, white text, and upward movement. The transition property smoothed the color and position changes. Try this: Add different hover colors for each navigation section.

Interactive Pseudo-Classes

Interactive pseudo-classes respond to user actions like clicking, hovering, and focusing. These are essential for creating engaging user interfaces that provide immediate feedback when users interact with elements. The `:hover` pseudo-class activates when users move their mouse over an element. The `:focus` pseudo-class triggers when users click into form fields or tab to buttons using their keyboard. The `:active` pseudo-class applies during the brief moment when users are clicking down on an element.
/* Style WanderLust contact form inputs with interactive states */
.contact-input {
  padding: 14px 16px; /* Comfortable click area */
  border: 2px solid #e2e8f0; /* Light gray border */
  border-radius: 8px; /* Rounded corners */
  transition: all 0.2s ease; /* Smooth state changes */
}

.contact-input:focus {
  border-color: #0ea5e9; /* Sky blue when clicked into */
  outline: none; /* Remove browser default outline */
  box-shadow: 0 0 0 3px rgba(14, 165, 233, 0.1); /* Subtle blue glow */
}
localhost/booking.html

Accessibility Matters

Always style both :hover and :focus states together. Mouse users see hover effects, but keyboard users who tab through forms only trigger focus states. Both groups deserve the same visual feedback.

Position-Based Pseudo-Classes

Position-based pseudo-classes select elements based on where they appear in the HTML structure. These selectors are perfect for styling the first item in a list differently, alternating row colors in tables, or highlighting the last paragraph in an article. The `:first-child` pseudo-class targets the first element among siblings. The `:last-child` selects the final element. The `:nth-child()` function lets you pick specific positions using numbers, keywords like `odd` and `even`, or mathematical formulas.
/* Style WanderLust destination cards with alternating patterns */
.destination-card:first-child {
  background: linear-gradient(135deg, #0ea5e9, #0284c7); /* Featured destination gets gradient */
  color: white; /* White text on blue background */
  transform: scale(1.05); /* Slightly larger than others */
}

.destination-card:nth-child(even) {
  background: #f8fafc; /* Even cards get light gray background */
  border-left: 4px solid #f97316; /* Orange accent border */
}

.destination-card:last-child {
  border: 2px dashed #22c55e; /* Last card gets green dashed border */
  background: #f0fdf4; /* Light green background */
}
localhost/destinations.html

What just happened?

The first destination card got a blue gradient background and larger size to make it stand out as featured. Even-numbered cards (2nd and 4th) received light backgrounds with orange borders. The last card got a green dashed border treatment. Try this: Use :nth-child(3n) to style every third item.

Link State Pseudo-Classes

Link pseudo-classes handle the four states that hyperlinks can exist in: unvisited, visited, hovered, and actively being clicked. These states help users understand which links they've already explored and provide feedback during interactions. The proper order for link pseudo-classes follows the mnemonic "LoVe HAte" — `:link` (unvisited), `:visited` (previously clicked), `:hover` (mouse over), and `:active` (being clicked). This order prevents the cascade from overriding states incorrectly.
/* WanderLust navigation links with all four states */
.destination-link:link {
  color: #0ea5e9; /* Sky blue for unvisited links */
  text-decoration: underline; /* Clear indication it's a link */
}

.destination-link:visited {
  color: #7c3aed; /* Purple for visited destinations */
  opacity: 0.8; /* Slightly faded to show it's been seen */
}

.destination-link:hover {
  color: #f97316; /* Orange highlight on hover */
  background: rgba(249, 115, 22, 0.1); /* Light orange background */
  text-decoration: none; /* Remove underline on hover */
}

.destination-link:active {
  color: #dc2626; /* Red flash while clicking */
  transform: translateY(1px); /* Tiny downward press effect */
}
localhost/destinations.html

Form Pseudo-Classes

Form pseudo-classes target input elements based on their validation state and user interaction. These selectors help create intuitive forms that guide users toward successful completion while clearly indicating errors or requirements. The `:required` pseudo-class targets form fields marked as mandatory. The `:valid` and `:invalid` pseudo-classes respond to HTML5 validation rules like email format or required fields. The `:disabled` pseudo-class styles inputs that users cannot interact with.
/* WanderLust booking form with smart validation styling */
.booking-input:required {
  border-left: 4px solid #f97316; /* Orange bar for required fields */
}

.booking-input:valid {
  border-color: #22c55e; /* Green border when input is correct */
  background: rgba(34, 197, 94, 0.05); /* Very light green background */
}

.booking-input:invalid:not(:placeholder-shown) {
  border-color: #ef4444; /* Red border only after user types invalid data */
  background: rgba(239, 68, 68, 0.05); /* Light red background */
}

.booking-input:disabled {
  background: #f1f5f9; /* Gray background for disabled fields */
  color: #94a3b8; /* Gray text color */
  cursor: not-allowed; /* Show disabled cursor */
}
localhost/booking.html

The :not(:placeholder-shown) part prevents invalid styling from appearing immediately when the page loads. Users only see red borders after they start typing, creating a friendlier experience than showing errors before they've had a chance to enter anything.

Advanced Pseudo-Class Combinations

You can combine multiple pseudo-classes on the same element to create very specific targeting rules. You can also chain different selectors with pseudo-classes to build complex conditional styling that responds to multiple factors simultaneously.
/* Combine pseudo-classes for precise WanderLust styling */
.team-member:first-child:hover {
  background: linear-gradient(45deg, #0ea5e9, #f97316); /* Featured team member gets special hover */
  color: white;
}

.pricing-card:nth-child(2):hover .price {
  transform: scale(1.2); /* Scale price in middle card only */
  color: #f97316; /* Orange highlight for recommended package */
}

.nav-link:not(:first-child):not(:last-child) {
  border-left: 1px solid #e2e8f0; /* Borders only on middle navigation items */
  border-right: 1px solid #e2e8f0;
}

button:hover:not(:disabled) {
  background: #0284c7; /* Hover effect only on enabled buttons */
  cursor: pointer;
}
localhost/about.html
The power of pseudo-classes becomes clear when you combine them strategically. You can target the first team member specifically during hover, scale prices only in featured pricing cards, add borders to middle navigation items while leaving the first and last untouched, and prevent hover effects on disabled buttons.

Interactive States

:hover, :focus, :active respond to user actions and create engaging interfaces

Position Selectors

:first-child, :last-child, :nth-child() target elements by their position in the HTML

Link States

:link, :visited, :hover, :active follow the "LoVe HAte" order for proper cascading

Form Validation

:required, :valid, :invalid, :disabled provide smart form feedback and guidance

Quiz

1. The WanderLust team wants to ensure both mouse and keyboard users see the same button highlight effects. Which two pseudo-classes should they style together?


2. WanderLust wants to add a light blue background to every other navigation link (1st, 3rd, 5th, etc.). Which selector accomplishes this?


3. In the WanderLust booking form, the selector `.email-input:invalid:not(:placeholder-shown)` is used instead of just `.email-input:invalid`. What's the benefit of this approach?


Up Next: Pseudo-Elements

Create and style virtual elements that don't exist in your HTML, like custom bullets, tooltips, and decorative overlays.