Skip to content
Home Tutorials Roadmaps Courses
Log in Join free
Tutorials CSS Pseudo-classes & Pseudo-elements
CSS Beginner FREE

Pseudo-classes & Pseudo-elements

Lesson 1 of 16 Beginner Interactive

Pseudo-classes select elements based on their state or position. Pseudo-elements create virtual elements for styling specific parts.

Common Pseudo-classes

  • :hover — when mouse is over the element
  • :focus — when the element has focus (input, button)
  • :active — while the element is being clicked
  • :first-child / :last-child — first/last child of parent
  • :nth-child(n) — nth child (e.g., :nth-child(odd), :nth-child(3n))
  • :not(selector) — selects elements NOT matching the selector
  • :disabled / :checked — form element states

Common Pseudo-elements

  • ::before — inserts content before the element
  • ::after — inserts content after the element
  • ::first-line — first line of text
  • ::first-letter — first letter of text
  • ::placeholder — styles input placeholders

Syntax

CSS
/* Pseudo-classes */
a:hover { color: #2563eb; }
input:focus { border-color: #2563eb; outline: none; }
li:first-child { font-weight: bold; }
li:nth-child(even) { background: #f8fafc; }
li:nth-child(3n) { color: red; }
button:disabled { opacity: 0.5; }

/* Pseudo-elements */
.quote::before {
    content: "\201C";
    font-size: 2rem;
    color: #2563eb;
}
.card::after {
    content: "";
    display: block;
    height: 4px;
    background: linear-gradient(to right, #2563eb, #7c3aed);
    margin-top: 12px;
}
p::first-line { font-weight: bold; }
input::placeholder { color: #94a3b8; }
Pseudo-classes and Pseudo-elements
HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Pseudo-classes & Pseudo-elements</title>
    <style>
        a:hover { color: #dc2626; }
        a:visited { color: #7c3aed; }
        input:focus { border-color: #3b82f6; }
        li:first-child { font-weight: bold; }
        li:not(.skip) { color: #374151; }
        h1::before { content: ">> "; color: #f59e0b; }
        p::after { content: " [end]"; color: #9ca3af; }
        ::selection { background: #fef08a; }
    </style>
</head>
<body>
    <h1>Pseudo Demo</h1>
    <ul>
        <li>first-child is bold</li>
        <li>not(.skip) gets color: #374151</li>
        <li class="skip">This item skips the rule.</li>
    </ul>
    <input type="text" placeholder="focus me">
    <p>Hover the <a href="#">link</a> to change its color.</p>
</body>
</html>

Practice

1
Exercise

Create an underline hover effect on links using ::after pseudo-element.

Answer
a {
    position: relative;
    text-decoration: none;
}
a::after {
    content: "";
    position: absolute;
    bottom: 0;
    left: 0;
    width: 0;
    height: 2px;
    background: blue;
    transition: width 0.3s;
}
a:hover::after {
    width: 100%;
}
2
Exercise

Style every even list item with a different background using :nth-child.

Answer
li:nth-child(even) {
    background-color: #f8fafc;
}

Quick Quiz

1

What is the difference between :hover and ::before?

:hover selects an element in a state (pseudo-class). ::before creates a virtual child element (pseudo-element).

2

What does ::before do?

::before creates a virtual first child element that appears before the actual content.

Interview Questions

Common uses: decorative icons (content: "\f007" with icon fonts), decorative quotes, gradient underlines, creating badges/labels, adding visual separators, and creating visual indicators without extra HTML elements. It keeps markup clean.

:nth-child(an+b) selects elements based on position. Common patterns: :nth-child(odd) for odd children, :nth-child(even) for even, :nth-child(3n) for every 3rd, :nth-child(3n+1) for offset. It counts among siblings regardless of type. :nth-of-type() counts only among elements of the same type.