CSS Topics
🎨 CSS Design✨Lesson 4 of 16

Pseudo-classes & Elements

Master interactive states (:hover, :focus, :active, :nth-child) and phantom styling elements (::before, ::after) without touching extra HTML tags.

⏱️~5 min read🟢Beginner⚡Jump to Code Editor

What you'll learn in this lesson

  1. 01Pseudo-classes: styling elements based on user interaction (:hover, :focus)
  2. 02Dynamic lists: alternating rows with :nth-child(even)
  3. 03Pseudo-elements: generating phantom content (::before, ::after)
  4. 04The magic 'content:' property required for pseudo-elements
  5. 05Single colon (:) vs double colon (::) explained
Pseudo-Class (Single Colon :)State / Condition
button:hover { background: purple; }

Targets an existing element only when it enters a specific state (hovered, clicked, focused, or nth child).

Pseudo-Element (Double Colon ::)Phantom Child
.card::before { content: "★"; }

Creates a virtual cosmetic element inside the tag without touching or adding extra HTML tags!

  1. 1

    The Chameleon Effect: Styling Interactivity with Pseudo-classes

    In real life, a button doesn't look like a dead piece of cardboard. When you move your mouse over it, it highlights; when you click it, it presses down; when you tab to an input, it glows.

    CSS handles this dynamic behavior using Pseudo-classes (prefixed by a single colon :). They match elements based on their temporal state:

    • :hover: Active when the user hovers a mouse cursor over the element.
    • :active: Active during the exact moment of a mouse click or tap.
    • :focus: Active when an input is clicked into or selected via keyboard tab.
    • :nth-child(even): Automatically stripes table rows or list items!
  2. 2

    Invisible Clones: Generating Content with ::before and ::after

    Often in UI design, you want to put a decorative icon, a star badge, or a gradient underline behind a heading. Adding empty <span></span> tags into your HTML purely for decorative reasons pollutes your markup.

    CSS solves this with Pseudo-elements (double colons ::). ::before injects a virtual child at the very start of the element, and ::after injects one at the very end.

  3. 3

    The Golden Rule of ::before & ::after: The content property

    A pseudo-element will never render on screen unless you supply the content property!

    Even if you only want to draw a decorative colored square or pill, you must write content: ""; (empty quotes). Think of content as turning on the power switch for the pseudo-element.

  4. 4

    Hands-On Practice: Interactive Button and Automatic Badge

    Look at the code below. Move your mouse over the button on the right to see :hover and :active in action. Notice how the star and (NEW) badges are inserted purely via CSS!

  5. 5

    Syntax Convention: Single Colon vs Double Colon

    In modern CSS3, single colon (:) is used for pseudo-classes (states), and double colon (::) is used for pseudo-elements (virtual DOM nodes). While browsers support single colon for both due to backward compatibility, using ::before and ::after is the modern industry standard.

Interactive Live Editor
styles.css
Click & type to editHTML5
Interactive Demo

Line by line

  1. .btn:hover { background-color: #4338ca; }

    Pseudo-class. Targets the button only when the user’s mouse pointer moves over it.

  2. .btn:active { transform: translateY(0); }

    Pseudo-class. Triggers precisely while the button is being actively clicked or tapped down.

  3. .pro-badge::before { content: "★ "; }

    Pseudo-element. Generates an amber star directly before the text without adding a span to HTML.

  4. .pro-badge::after { content: " (NEW)"; }

    Pseudo-element. Generates a green 'NEW' badge right after the text.

Try it yourself

Create a link with class .custom-link that turns red on :hover, and automatically adds an arrow → after the link using ::after.

Hint: Remember to write content: " →"; inside the ::after block!

💡 View Solution (if stuck)
.custom-link {
  color: #4f46e5;
  text-decoration: none;
  font-weight: bold;
}

.custom-link:hover {
  color: #ef4444;
}

.custom-link::after {
  content: " →";
  transition: transform 0.2s ease;
}
Quick Knowledge Check

What happens if you define a ::before or ::after pseudo-element without the 'content' property?

Common mistakes

  • 1.Forgetting content: ""; on ::before or ::after. Without it, the pseudo-element is invisible.
  • 2.Trying to apply ::before or ::after on void tags like <img> or <input> (they have no child container).
  • 3.Confusing :focus (keyboard/input selection) with :active (mouse button held down).

Interview prep (Click to reveal)

Q: What is the difference between a pseudo-class and a pseudo-element?▼

A pseudo-class (e.g. :hover, :focus) selects an existing element based on its dynamic state. A pseudo-element (e.g. ::before, ::after) creates a virtual cosmetic sub-element that does not exist in the HTML DOM.

Q: Can you use ::before and ::after on an <img> or <input> tag?▼

No! ::before and ::after insert pseudo-elements inside the target container as its first or last child. Because <img> and <input> are void (replaced) elements with no closing tag or inner content, they cannot contain pseudo-elements.

Q: How does :nth-child(even) work in real-world table design?▼

tr:nth-child(even) targets every 2nd, 4th, 6th, etc. row in a table. It allows creating 'zebra striping' with alternating background colors dynamically, without having to manually add class names to HTML rows.