CSS Pseudo-classes
Style elements based on their state or position
🎯 What are CSS Pseudo-classes?
Pseudo-classes are keywords that specify a special state of an element. They allow you to style elements when they're being hovered over, focused, or in specific positions.
/* Style links when hovered */
a:hover {
color: red;
text-decoration: underline;
}
Common Pseudo-classes
:hover
When mouse is over element
button:hover { background: blue; }
:focus
When element has focus
input:focus { border: 2px solid blue; }
:active
When element is being clicked
button:active { transform: scale(0.95); }
:visited
For visited links
a:visited { color: purple; }
🔹 Interactive Button Example
Interactive button implementations demonstrate CSS pseudo-classes including :hover, :focus, and :active creating visual feedback states. These states provide essential user experience affordances indicating interactive availability and activation status. Implementation combines transition animations with appropriate timing functions for smooth state changes. Accessible buttons include proper ARIA attributes and keyboard navigation support, ensuring universal usability that positively impacts engagement metrics.
<!-- HTML -->
<button class="interactive-btn">Hover Me!</button>
/* CSS */
.interactive-btn {
background-color: #4CAF50;
color: white;
padding: 15px 30px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
transition: all 0.3s ease;
}
.interactive-btn:hover {
background-color: #45a049;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
.interactive-btn:active {
transform: translateY(0);
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
.interactive-btn:focus {
outline: 3px solid #81C784;
}
Output (try hovering and clicking):
🔹 Structural Pseudo-classes
Structural pseudo-classes target HTML elements based on their position within the document tree or a parent container. Key selectors include :first-child to style the first element, :last-child for the last, and :nth-child() for precise positional targeting—such as odd/even rows for table striping. :nth-of-type() filters by element type, enabling advanced layouts like alternating card styles. These selectors enhance maintainability by removing the need for manual class assignments, keeping HTML clean. They are essential for creating dynamic, data-driven interfaces where content order may change, ensuring consistent styling without extra markup.
<!-- HTML -->
<ul class="item-list">
<li>First item</li>
<li>Second item</li>
<li>Third item</li>
<li>Fourth item</li>
<li>Last item</li>
</ul>
/* CSS */
.item-list li:first-child {
background-color: lightgreen;
font-weight: bold;
}
.item-list li:last-child {
background-color: lightcoral;
font-weight: bold;
}
.item-list li:nth-child(even) {
background-color: #f0f0f0;
}
.item-list li:nth-child(3) {
background-color: lightyellow;
border-left: 4px solid orange;
}
Output:
- First item
- Second item
- Third item
- Fourth item
- Last item
🔹 Form Pseudo-classes
Form pseudo-classes apply styles based on the state or validity of form elements, improving user interaction and accessibility. :focus highlights the active input, :checked styles selected checkboxes/radio buttons, and :disabled visually greys out non-interactive fields. Validation states like :valid and :invalid provide immediate feedback using color cues (green for correct, red for errors). :required and :optional differentiate mandatory fields. These pseudo-classes help guide users through forms, reduce submission errors, and enhance UX by making interface states clear, which can improve form completion rates and overall site engagement.
<!-- HTML -->
<form class="demo-form">
<input type="text" placeholder="Enter your name" required>
<input type="email" placeholder="Enter your email" required>
<input type="checkbox" id="agree">
<label for="agree">I agree to terms</label>
</form>
/* CSS */
.demo-form input:focus {
border: 2px solid #4CAF50;
outline: none;
box-shadow: 0 0 5px rgba(76, 175, 80, 0.3);
}
.demo-form input:valid {
border-color: green;
}
.demo-form input:invalid {
border-color: red;
}
.demo-form input:checked + label {
color: green;
font-weight: bold;
}
.demo-form input:disabled {
background-color: #f5f5f5;
cursor: not-allowed;
}
Output (try typing in the fields):
🔹 Link States
Link state pseudo-classes style anchor elements based on user interaction, following the LVHA order: :link, :visited, :hover, :active. :link defines unvisited links, typically blue. :visited applies to previously clicked links, often purple. :hover triggers on mouse-over for visual feedback. :active styles the link during the click moment. Maintaining this order prevents specificity conflicts and ensures predictable behavior. Properly styled link states enhance navigation clarity, improve user experience by providing interactive feedback, and support accessibility for keyboard and screen reader users. Clear visual cues also encourage deeper site exploration, boosting SEO through improved engagement metrics.
<!-- HTML -->
<div class="link-demo">
<a href="#" class="demo-link">Normal Link</a>
<a href="#" class="demo-link visited-link">Visited Link</a>
</div>
/* CSS - Remember LVHA order! */
.demo-link:link {
color: blue;
text-decoration: none;
}
.demo-link:visited {
color: purple;
}
.demo-link:hover {
color: red;
text-decoration: underline;
}
.demo-link:active {
color: orange;
}
Output (try hovering over the links):
🔹 Advanced Pseudo-classes
Advanced pseudo-classes enable complex selection logic for sophisticated UI patterns and conditional styling. :not() excludes elements matching a selector, useful for applying styles broadly with exceptions. :empty targets elements with no children, allowing hidden placeholder cleanup. :target styles the element referenced in the URL fragment, enabling CSS-only tab systems. :lang() applies locale-specific styles. These selectors reduce JavaScript dependency, enhance performance, and keep stylesheets maintainable. They empower developers to create responsive, interactive components—like filtered galleries or dynamic notifications—purely with CSS, improving page load times and core web vitals, which are critical SEO ranking factors.
Useful Advanced Pseudo-classes:
- :not() - Selects elements that don't match a selector
- :nth-of-type() - Selects elements by type and position
- :empty - Selects elements with no content
- :root - Selects the document root (html element)
/* Examples */
p:not(.special) {
color: gray;
}
img:nth-of-type(odd) {
float: left;
}
div:empty {
display: none;
}
:root {
--main-color: #4CAF50;
}