Mudzinga

Discover how CSS ::before and ::after can add icons, labels, and decorations without changing your HTML. Learn with simple, hands-on examples—click to start coding!

5 Minute Read

Pseudo-Elements: Before and After

Pseudo-Elements: Before and After

If you’ve ever wished you could add a small label, icon, or decoration to your web page without changing the HTML, pseudo-elements are your new best friend.

In this article, you’ll learn what ::before and ::after are, why they’re useful, and how to use them step-by-step. We’ll walk through clear examples you can copy, paste, and tweak—even if you’re just starting out with HTML and CSS.


What are pseudo-elements?

A pseudo-element is a way to style specific parts of an element using CSS, without adding extra tags in your HTML.

Two of the most useful pseudo-elements are:

  • ::before – creates a virtual element before the content inside an element
  • ::after – creates a virtual element after the content inside an element

Think of them as invisible boxes that you can make appear before or after your text. You can then add text, icons, or shapes inside those boxes with CSS.

Important: Pseudo-elements need a content property to appear. Even if you don’t want any text, you still need content: "";.


Getting set up (HTML + CSS)

Let’s start with a tiny HTML page and a linked CSS file.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Pseudo-Elements Example</title>
  <link rel="stylesheet" href="styles.css" />
</head>
<body>
  <h1 class="title">Welcome to My Page</h1>
</body>
</html>

styles.css

body {
  font-family: Arial, sans-serif; /* Friendly, readable font */
  padding: 20px;
}

.title {
  color: #333; /* Dark gray text */
}

Open this in your browser. You should see a simple page with “Welcome to My Page.” Now we’ll add some magic with ::before and ::after.


Example 1: Adding a label with ::before

Let’s add a small label before the title.

styles.css (add this below the existing .title rule)

.title::before {
  content: "NEW! ";              /* Text that appears before the title */
  color: #e53935;                 /* Red text color for the label */
  font-weight: bold;              /* Make the label bold */
}

What this does

  • title::before targets the pseudo-element just before the .title text.
  • content: "NEW! "; tells the browser to show the word NEW! before the heading.
  • The space at the end of "NEW! " is important—it adds a little gap before the real title.

Expected result: Your heading should now look like this:

NEW! Welcome to My Page

in your chosen colors.

Try it yourself

Change the label text to something else, like:

content: "🔥 Hot: ";

or

content: "[Featured] ";

Notice how you can change the text in CSS without touching the HTML.


Example 2: Adding a note with ::after

Now let’s add a short note after the title using ::after.

styles.css (add this rule)

.title::after {
  content: " (updated today)";   /* Text that appears after the title */
  color: #777;                    /* Lighter gray color */
  font-size: 0.9em;               /* Slightly smaller than the main text */
}

What this does

  • title::after creates a pseudo-element right after the text "Welcome to My Page".
  • The note appears inline, like part of the same line.

Expected result:

NEW! Welcome to My Page (updated today)

Try it yourself

Change the message to something else, or remove the space at the beginning of the content to see how it affects the spacing:

content: "(updated today)";  /* No space before the parentheses */

You’ll see the note move closer to the title.


Example 3: Creating a decorative line with ::before

Pseudo-elements don’t have to show text. They can also act as shapes or decorations.

Let’s add a colored line above the title using ::before as a block element.

First, we’ll remove the text label from ::before and turn it into a line.

Update your styles.css

.title::before {
  content: "";               /* Empty content, but still required */
  display: block;             /* Make it act like a block element */
  width: 60px;                /* Line width */
  height: 4px;                /* Line thickness */
  background-color: #e53935;  /* Line color */
  margin-bottom: 8px;         /* Space between line and title */
}

.title::after {
  content: " (updated today)";
  color: #777;
  font-size: 0.9em;
}

What this does

  • content: ""; still needed—without it, nothing shows.
  • display: block; makes the pseudo-element behave like a block (like a <div>), so it can have width and height.
  • background-color, width, and height turn it into a small bar.
  • margin-bottom adds space between the line and the text.

Expected result: You should see a red bar above your heading, with the small note after the title.

Try it yourself

Experiment with:

  • Changing the color
  • Increasing the width to 100px or more
  • Increasing the height to make it look like a thick banner

Example 4: Adding icons before list items

Pseudo-elements are great for custom bullets in lists. Let’s create a simple list and add icons using ::before.

index.html (add this under your <h1>)

<ul class="features">
  <li>Fast setup</li>
  <li>Easy to customize</li>
  <li>Beginner-friendly</li>
</ul>

styles.css (add these rules)

.features {
  list-style: none;        /* Remove default browser bullets */
  padding-left: 0;         /* Remove extra left padding */
}

.features li {
  margin: 6px 0;           /* Space between list items */
}

.features li::before {
  content: "✔ ";           /* Checkmark icon + space */
  color: #43a047;          /* Green color for the checkmark */
  font-weight: bold;       /* Make the checkmark stand out */
}

What this does

  • list-style: none; hides the default bullets.
  • .features li::before adds a green checkmark before each list item.
  • Because we used a space after the checkmark in "✔ ", the text doesn’t touch the icon.

Expected result: Your list items should each start with a green checkmark.

Try it yourself

  • Replace "✔ " with another symbol like "➡ ", "★ ", or any emoji.
  • Change the color to match your design.

If your keyboard doesn’t easily type these symbols, you can copy and paste them from the web.


Common mistakes (and how to fix them)

Here are a few issues beginners often run into with ::before and ::after:

  1. Nothing shows up

    • Did you include content? You need content: ""; even if it’s empty.
  2. Spacing looks weird

    • Check if you included spaces in your content string.
    • Example: "NEW! " vs "NEW!".
  3. Styles not applying

    • Make sure your class or element name matches exactly in HTML and CSS.
    • Example: .title in CSS must match class="title" in HTML.

Try it yourself: Your mini project

Create a simple section titled “Tasks for Today” with a list of tasks. Use pseudo-elements to:

  1. Add a decorative line above the heading using ::before.
  2. Add a small note after the heading using ::after.
  3. Use ::before on each list item to add a custom bullet.

You already have all the pieces from the examples above. Mix and match them into your own little design.

Don’t worry if it doesn’t look perfect. Just getting something to appear is a huge win when you’re starting out.


Quick recap

Let’s summarize what you’ve learned:

  • ::before and ::after create extra, virtual elements before and after your real content.
  • They must have a content property to show up, even if it’s empty.
  • You can use them for:
    • Labels and notes (text)
    • Icons and custom bullets
    • Decorative lines and shapes
  • They help you style your page without adding extra HTML elements.

You’ve just taken an important step into CSS layout and styling. Keep experimenting—change colors, sizes, and content values. With each small tweak you make, you’ll get more comfortable and confident with CSS.

Next steps: try using ::before and ::after on buttons, navigation menus, or card components. Tiny visual touches can make your pages feel much more polished, and now you know how to add them with just a few lines of CSS.

About Percy Mudzinga

This article was automatically generated by an AI-powered blog system built by Percy.
Percy Mudzinga is a Senior Full-Stack Software Engineer based in Harare, Zimbabwe, with nearly a decade of experience building enterprise web and mobile applications. He specializes in React, Vue.js, Flutter, and Node.js.

Never Miss an Update

Subscribe to our newsletter and get the latest articles delivered directly to your inbox every week.

No spam, unsubscribe anytime. We respect your privacy.

© 2025 Mudzinga. All rights reserved.