Ultimate Guide to CSS Pseudo-Classes and Pseudo-Elements



This content originally appeared on DEV Community and was authored by Maxim Logunov

Pseudo-classes (:pseudo-class) and pseudo-elements (::pseudo-element) are powerful CSS tools that allow you to style elements based on their state or position in the DOM. This comprehensive guide covers all major pseudo-classes and pseudo-elements with practical examples and explanations.

1. Pseudo-Classes

Pseudo-classes select elements in specific states.

1.1. Link and Interaction States

Pseudo-Class Example Description
:link a:link { color: blue; } Unvisited links
:visited a:visited { color: purple; } Visited links
:hover button:hover { background: #eee; } Element on mouse hover
:active a:active { color: red; } Element being clicked
:focus input:focus { border-color: blue; } Focused form element

1.2. Form States

Pseudo-Class Example Description
:checked input:checked { accent-color: green; } Checked checkboxes/radio buttons
:disabled input:disabled { opacity: 0.5; } Disabled form elements
:enabled input:enabled { border: 1px solid #ccc; } Enabled form elements
:valid input:valid { border-color: green; } Valid form input
:invalid input:invalid { border-color: red; } Invalid form input
:placeholder-shown input:placeholder-shown { color: gray; } Input showing placeholder text

1.3. Structural and Positional

Pseudo-Class Example Description
:first-child li:first-child { font-weight: bold; } First child element
:last-child li:last-child { border-bottom: none; } Last child element
:nth-child(n) tr:nth-child(odd) { background: #f5f5f5; } Elements matching position (even, odd, formulas)
:first-of-type p:first-of-type { font-size: 1.2em; } First element of its type
:last-of-type p:last-of-type { margin-bottom: 0; } Last element of its type
:empty div:empty { display: none; } Empty elements (no children)
:not() div:not(.hidden) { display: block; } Elements not matching selector

2. Pseudo-Elements

Pseudo-elements style specific parts of elements or generate content.

Pseudo-Element Example Description
::before p::before { content: "→ "; } Inserts content before element
::after button::after { content: " »"; } Inserts content after element
::first-letter p::first-letter { font-size: 2em; } Styles first letter of text
::first-line p::first-line { font-weight: bold; } Styles first line of text
::selection ::selection { background: yellow; } Styles selected text
::placeholder input::placeholder { color: #999; } Styles placeholder text
::marker li::marker { color: red; } Styles list markers

3. Practical Examples

3.1. Styling Lists

/* Alternate row colors */
li:nth-child(even) {
  background: #f9f9f9;
}

/* Drop-cap effect */
p::first-letter {
  font-size: 1.5em;
  color: darkblue;
}

3.2. Interactive Buttons

button {
  padding: 10px 20px;
  transition: background 0.3s;
}

button:hover {
  background: #ddd;
}

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

3.3. Custom Checkboxes

input[type="checkbox"]:checked + label {
  font-weight: bold;
  color: green;
}

4. Key Takeaways

Pseudo-classes and pseudo-elements enable you to:
✅ Create dynamic, state-dependent styles

✅ Precisely target elements by DOM position

✅ Add decorative elements without extra HTML

Bookmark this cheat sheet to build more interactive and stylish interfaces! 🚀


This content originally appeared on DEV Community and was authored by Maxim Logunov