Pseudo-classes and Pseudo-elements
Pseudo-classes and pseudo-elements let you style elements based on their state or position in the document. They start with a colon (:) and give you extra control over styling.
What are Pseudo-classes?
Pseudo-classes select elements based on their state or relationship to other elements. They help you style elements dynamically without adding extra classes.
Common Pseudo-classes
:hover
Styles an element when the mouse hovers over it.
button:hover {
background-color: #007bff;
color: white;
}:active
Styles an element when it’s being activated (clicked).
button:active {
transform: scale(0.98);
}:focus
Styles an element when it has focus (like form inputs).
input:focus {
border-color: #007bff;
outline: none;
}:first-child and :last-child
Select the first or last child of a parent.
.list-item:first-child {
border-top: none;
}
.list-item:last-child {
border-bottom: none;
}:nth-child()
Select elements based on their position.
.row:nth-child(odd) {
background-color: #f5f5f5; /* Alternate row colors */
}
.item:nth-child(3n+1) { /* Every 3rd item starting from 1 */
color: red;
}:not()
Exclude elements from a selection.
button:not(.disabled) {
cursor: pointer;
}What are Pseudo-elements?
Pseudo-elements create virtual elements that don’t exist in the HTML. They start with double colons (::) in modern CSS.
Common Pseudo-elements
::before and ::after
Add content before or after an element.
.quote::before {
content: '"';
font-size: 2em;
color: #007bff;
}
.quote::after {
content: '"';
font-size: 2em;
color: #007bff;
}::first-letter
Style the first letter of text.
.article::first-letter {
font-size: 3em;
float: left;
margin-right: 0.1em;
}::first-line
Style the first line of text.
.paragraph::first-line {
font-weight: bold;
color: #007bff;
}::selection
Style selected text.
::selection {
background-color: #007bff;
color: white;
}Practical Examples
Button States
Style different button states for better UX.
.button {
padding: 10px 20px;
background: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s;
}
.button:hover {
background: #e9ecef;
border-color: #adb5bd;
}
.button:active {
background: #dee2e6;
transform: translateY(1px);
}
.button:focus {
outline: none;
box-shadow: 0 0 0 2px rgba(0,123,255,0.25);
}Navigation Menu
Highlight active menu items.
.nav-item {
padding: 10px 15px;
text-decoration: none;
color: #333;
}
.nav-item:hover {
background-color: #f8f9fa;
}
.nav-item.active {
background-color: #007bff;
color: white;
}
/* Or use pseudo-classes */
.nav-item:not(.active):hover {
background-color: #f8f9fa;
}Form Styling
Improve form usability with focus states.
.form-group {
margin-bottom: 1rem;
}
.form-label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
}
.form-input {
width: 100%;
padding: 0.5rem;
border: 1px solid #ced4da;
border-radius: 0.25rem;
}
.form-input:focus {
border-color: #007bff;
box-shadow: 0 0 0 2px rgba(0,123,255,0.25);
}
.form-input:invalid {
border-color: #dc3545;
}Card Layout with Icons
Use ::before for decorative icons.
.card {
border: 1px solid #dee2e6;
border-radius: 0.25rem;
padding: 1rem;
}
.feature-card::before {
content: '★';
font-size: 1.5em;
color: #ffc107;
margin-right: 0.5rem;
}Striped Table
Alternate row colors using nth-child.
.table tr:nth-child(even) {
background-color: #f8f9fa;
}
.table tr:hover {
background-color: #e9ecef;
}Drop Cap
Style the first letter of paragraphs.
.article p:first-child::first-letter {
font-size: 3em;
float: left;
margin-right: 0.1em;
margin-top: 0.1em;
line-height: 0.8;
font-weight: bold;
color: #007bff;
}Combining Pseudo-classes and Pseudo-elements
You can combine them for more specific styling.
.article p:first-child::first-line {
font-weight: bold;
}
.list-item:nth-child(odd):hover {
background-color: #fff3cd;
}Browser Support
Most pseudo-classes and pseudo-elements are well supported:
- Chrome: Full support
- Firefox: Full support
- Safari: Full support
- Edge: Full support
Some older pseudo-elements use single colon (:) but double colon (::) is preferred.
Best Practices
- Use semantic HTML with pseudo-classes
- Test hover states on touch devices
- Provide visible focus indicators for accessibility
- Don’t rely on content generated with ::before/::after for important information
- Use nth-child for patterns instead of adding classes
Accessibility Considerations
- Ensure focus states are visible
- Don’t remove focus outlines without replacement
- Test hover effects on mobile devices
- Use semantic HTML that pseudo-classes can target
Common Use Cases
- Interactive elements: Hover, focus, active states
- Form styling: Focus and validation states
- Navigation: Active and hover states
- Tables: Alternating row colors
- Typography: First letter and line styling
- Decorative elements: Icons and quotes
External Resources:
Related Tutorials: