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
contentproperty to appear. Even if you don’t want any text, you still needcontent: "";.
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::beforetargets the pseudo-element just before the.titletext.content: "NEW! ";tells the browser to show the wordNEW!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::aftercreates 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, andheightturn it into a small bar.margin-bottomadds 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
100pxor 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::beforeadds 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:
Nothing shows up
- Did you include
content? You needcontent: "";even if it’s empty.
- Did you include
Spacing looks weird
- Check if you included spaces in your
contentstring. - Example:
"NEW! "vs"NEW!".
- Check if you included spaces in your
Styles not applying
- Make sure your class or element name matches exactly in HTML and CSS.
- Example:
.titlein CSS must matchclass="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:
- Add a decorative line above the heading using
::before. - Add a small note after the heading using
::after. - Use
::beforeon 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:
::beforeand::aftercreate extra, virtual elements before and after your real content.- They must have a
contentproperty 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.
