CSS Pseudo-selectors

A comprehensive guide to CSS pseudo-classes and pseudo-elements with practical examples

Introduction

CSS pseudo-selectors allow you to style elements based on their state or position, or to style specific parts of elements. They're divided into two main categories:

Pseudo-classes (:)

Select elements based on their state, position, or other characteristics

Pseudo-elements (::)

Style specific parts of elements or insert content before/after

Interactive Examples

Pseudo-class :hover

Matches when user interacts with element

a:hover {
  color: red;
}

Pseudo-class :focus

Matches when element has focus

input:focus {
  border-color: blue;
}

Pseudo-class :active

Matches when element is being activated

button:active {
  transform: scale(0.98);
}

Pseudo-class :first-child

Matches the first child element

li:first-child {
  font-weight: bold;
}
  • First item
  • Second item
  • Third item

Pseudo-class :last-child

Matches the last child element

li:last-child {
  font-style: italic;
}
  • First item
  • Second item
  • Third item

Pseudo-class :nth-child

Matches elements based on their position

li:nth-child(odd) {
  background: #f0f0f0;
}

li:nth-child(3n) {
  color: blue;
}
  • Item 1
  • Item 2
  • Item 3
  • Item 4
  • Item 5
  • Item 6

Pseudo-element ::before

Inserts content before an element

blockquote::before {
  content: "“";
  font-size: 3em;
  color: #ccc;
}
This is a quote with ::before content.

Pseudo-element ::after

Inserts content after an element

.price::after {
  content: " USD";
  font-size: 0.9em;
  color: #666;
}

29.99

Pseudo-class :checked

Matches checked radio/checkbox

input:checked + label {
  font-weight: bold;
}

Pseudo-class :disabled

Matches disabled elements

button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

Pseudo-class :not()

Negation pseudo-class

li:not(.special) {
  color: #999;
}
  • Regular item
  • Special item
  • Another regular item

Pseudo-element ::selection

Styles selected text

::selection {
  background: #ff0;
  color: #000;
}

Select this text to see the effect

Pseudo-class :hover

Matches when user interacts with element

a:hover {
  color: red;
}

Pseudo-class :focus

Matches when element has focus

input:focus {
  border-color: blue;
}

Pseudo-element ::before

Inserts content before an element

blockquote::before {
  content: "“";
  font-size: 3em;
  color: #ccc;
}
This is a quote with ::before content.

Pseudo-element ::after

Inserts content after an element

.price::after {
  content: " USD";
  font-size: 0.9em;
  color: #666;
}

29.99

Pseudo-class :checked

Matches checked radio/checkbox

input:checked + label {
  font-weight: bold;
}

Pseudo-class :disabled

Matches disabled elements

button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

Pseudo-class :valid

Matches valid form elements

input:valid {
  border-color: green;
}

Pseudo-class :invalid

Matches invalid form elements

input:invalid {
  border-color: red;
}

Pseudo-class :first-child

Matches the first child element

li:first-child {
  font-weight: bold;
}
  • First item
  • Second item
  • Third item

Pseudo-class :last-child

Matches the last child element

li:last-child {
  font-style: italic;
}
  • First item
  • Second item
  • Third item

Pseudo-class :nth-child

Matches elements based on their position

li:nth-child(odd) {
  background: #f0f0f0;
}

li:nth-child(3n) {
  color: blue;
}
  • Item 1
  • Item 2
  • Item 3
  • Item 4
  • Item 5
  • Item 6

Pseudo-class :not()

Negation pseudo-class

li:not(.special) {
  color: #999;
}
  • Regular item
  • Special item
  • Another regular item

Reference Table

Selector Type Description
:hover Pseudo-class Matches when user interacts with element
:active Pseudo-class Matches when element is being activated
:focus Pseudo-class Matches when element has focus
:first-child Pseudo-class Matches the first child element
:last-child Pseudo-class Matches the last child element
:nth-child() Pseudo-class Matches elements based on position
::before Pseudo-element Creates generated content before
::after Pseudo-element Creates generated content after
:checked Pseudo-class Matches checked radio/checkbox
:disabled Pseudo-class Matches disabled form elements
:not() Pseudo-class Negation pseudo-class
::selection Pseudo-element Styles selected text

Best Practices

Compatibility

  • Use single colon (:) for pseudo-elements in older browsers (CSS2)
  • Modern browsers support double colon (::) for pseudo-elements (CSS3)
  • Test in target browsers for differences in behavior

Performance

  • Avoid complex :nth-child() selectors for large DOM trees
  • Limit ::before/::after content to minimal CSS-injected content
  • Combine pseudo-selectors with element selectors when possible

Mobile Considerations

  • :hover states may need explicit :active states for touch devices
  • Use media queries to adjust pseudo-element content
  • Consider touch targets when using interactive pseudo-classes

Accessibility

  • Don't rely solely on :hover for functionality
  • Ensure :focus styles are visible for keyboard navigation
  • Test with screen readers when using ::before/::after for content

AdMob/Play Policies

  • Avoid content shifts that might trigger accidental clicks
  • Ensure :hover effects don't obscure required content
  • Disable :hover on mobile devices if it causes usability issues
  • Make sure :focus styles meet contrast requirements