CSS Pseudo-Elements

A pseudo-element lets you style a specific part of an element, or even create entirely new visual content without adding extra HTML tags. They use double colons (::) to distinguish them from pseudo-classes.

Think of pseudo-elements as invisible editing markers inside your content — you can style the first letter of a paragraph, insert a decorative symbol before a heading, or style text the user has selected, all without touching the HTML.

Pseudo-Element vs Pseudo-Class

DIAGRAM — Pseudo-Class vs Pseudo-Element:

:hover        → targets the WHOLE element in a certain STATE
::first-letter → targets a PART of the element's content

Both use the same colon notation, but double colons (::)
are the modern standard for pseudo-elements.

::before — Insert Content Before

::before creates a virtual element that appears before the element's actual content. You must use the content property — even if you set it to an empty string.

h2::before {
  content: "📌 ";
}
DIAGRAM — ::before in action:

HTML:   <h2>Introduction</h2>
Output: 📌 Introduction

The emoji is not in the HTML.
CSS ::before created it.

Common Use: Decorative Labels

.required-field::before {
  content: "* ";
  color: red;
  font-weight: bold;
}

Common Use: Icons from CSS

blockquote::before {
  content: "\201C"; /* left double quotation mark " */
  font-size: 3rem;
  color: lightgray;
  display: block;
}

::after — Insert Content After

::after works exactly like ::before but places the virtual element after the element's content.

a[target="_blank"]::after {
  content: " ↗";
  font-size: 0.8em;
  color: gray;
}

This adds an arrow icon after every external link automatically — no extra HTML needed.

Common Use: Clearfix

Before Flexbox and Grid, developers used ::after to fix float layout issues:

.clearfix::after {
  content: "";
  display: block;
  clear: both;
}

Common Use: Tooltip Arrows

.tooltip::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  border: 6px solid transparent;
  border-top-color: black;
}

::before and ::after as Layout Elements

When you set display: block or position: absolute on ::before or ::after, they become full layout elements — useful for decorative shapes, backgrounds, and badges.

DIAGRAM — ::before as a decorative bar:

h2::before {
  content: "";
  display: block;
  width: 40px;
  height: 4px;
  background: blue;
  margin-bottom: 8px;
}

Visual output:
────                ← blue bar from ::before
My Heading Text

::first-letter — Style the First Character

::first-letter targets the very first letter of a block-level element. This is the classic "drop cap" technique used in magazines and books.

p::first-letter {
  font-size: 3rem;
  font-weight: bold;
  float: left;
  line-height: 1;
  margin-right: 4px;
  color: darkred;
}
DIAGRAM — Drop Cap:

T his is the beginning of a long paragraph.
↑
The "T" is large, bold, and floated left.
The rest of the text wraps around it.

::first-letter only works on block-level elements like <p>, <div>, or headings.

::first-line — Style the First Line

::first-line styles only the first displayed line of text. The "first line" changes dynamically as the window is resized — CSS handles this automatically.

p::first-line {
  font-variant: small-caps;
  letter-spacing: 2px;
  color: gray;
}
DIAGRAM — ::first-line:

FIRST LINE STYLED IN SMALL CAPS
This is the second line, normal style.
And this is the third line, also normal.

::selection — Style Highlighted Text

::selection applies to text the user highlights with a mouse or keyboard.

::selection {
  background-color: #ffcc00;
  color: black;
}

/* Or target specific elements */
p::selection {
  background-color: darkblue;
  color: white;
}

Only color, background-color, and a few other properties work on ::selection. Complex layout properties are ignored.

::placeholder — Style Input Placeholder Text

The placeholder text inside an input shows before the user types. ::placeholder styles it.

input::placeholder {
  color: #aaa;
  font-style: italic;
}
DIAGRAM — ::placeholder:

[ Enter your email address... ]
  ↑ This greyed-out hint text is the placeholder

::marker — Style List Bullets and Numbers

::marker targets the bullet or number in front of a list item.

li::marker {
  color: red;
  font-size: 1.2em;
}

/* Custom marker content */
li.done::marker {
  content: "✅ ";
}

Rules for ::before and ::after

  • The content property is required. Without it, the pseudo-element does not render at all.
  • Use content: "" for decorative shapes that need no text.
  • They are inline by default. Add display: block or display: inline-block to use width and height.
  • They inherit styles from their parent element.
  • They appear in the rendered page but not in the actual HTML source.

Pseudo-Elements Quick Reference

Pseudo-ElementWhat It Targets
::beforeVirtual element inserted before content
::afterVirtual element inserted after content
::first-letterThe first character of a block element
::first-lineThe first displayed line of a block element
::selectionText highlighted by the user
::placeholderInput placeholder text
::markerList item bullet or number

Pseudo-elements give you styling hooks into parts of your content that no HTML element wraps — keeping your markup lean while achieving rich visual results.

Leave a Comment

Your email address will not be published. Required fields are marked *