Pseudo-classes and Pseudo-elements

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

  1. Use semantic HTML with pseudo-classes
  2. Test hover states on touch devices
  3. Provide visible focus indicators for accessibility
  4. Don’t rely on content generated with ::before/::after for important information
  5. 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:

Last updated on