Skip to content

Pseudo-Elements

Pseudo-elements are similar in syntax to pseudo-classes, but they do something fundamentally different. Where pseudo-classes target an element in a particular state, pseudo-elements target a part of an element — or insert generated content that does not exist in the HTML.

Pseudo-elements use a double colon (::) prefix.

::before inserts generated content before the element’s actual content. ::after inserts generated content after it. Neither element appears in the HTML — they are created entirely by CSS.

Both require the content property. Without content, the pseudo-element does not render.

.tour-name::before {
content: "";
color: #2c4a1e;
}

Result: every .tour-name element now visually displays an arrow before its text — without touching the HTML.

/* Decorative separator after sections */
section::after {
content: "";
display: block;
width: 60px;
height: 3px;
background-color: #2c4a1e;
margin-top: 2rem;
}

When content: "" is an empty string, the pseudo-element renders as a visible box — useful for decorative shapes and dividers. The element still needs display: block (or similar) and dimensions to be visible.

Targets only the first rendered line of a block element. The “first line” is determined by the browser — it changes as the viewport width changes.

article > p:first-child::first-line {
font-weight: bold;
font-size: 1.1rem;
}

This is useful for drop-cap article intros or styled opening lines. You cannot reliably control exactly how many words are in the “first line.”

Targets only the first letter of a block element. Classic use: the drop-cap effect.

article > p:first-child::first-letter {
font-size: 3rem;
float: left;
line-height: 0.8;
margin-right: 0.1em;
color: #2c4a1e;
}

float: left is a legacy CSS property originally designed for text-wrap layout — wrapping text around images. It has been largely replaced by Flexbox and Grid for general layout. The drop-cap pattern is one of the few cases where float is still the standard approach: it pulls the enlarged letter out of the flow and lets the remaining text wrap beside it.

Targets the placeholder text inside <input> and <textarea> elements.

input::placeholder,
textarea::placeholder {
color: #aaa;
font-style: italic;
}

Placeholder text is often too light or too stylistically similar to actual input text. ::placeholder lets you distinguish it clearly.

Pseudo-classPseudo-element
Syntax:hover, :focus::before, ::after
TargetsState of the whole elementA part of the element
Examples:hover, :first-child::before, ::placeholder

You will sometimes see pseudo-elements written with a single colon (:before, :after) in older code. This is legacy syntax from CSS2. The double colon (::) is the correct modern syntax — use it.

content is required for ::before and ::after. It accepts:

  • A text string: content: "→ " — renders that text
  • An empty string: content: "" — creates an empty box (for decorative shapes)
  • A URL: content: url(icon.svg) — embeds an image
  • none or normal — removes the pseudo-element

content has no effect on any element other than ::before and ::after.

Add pseudo-element styles to your Summit Trail Outfitters pages:

  1. Decorative prefix on tour names — add a character before each tour card heading:
.tour-name::before {
content: "";
color: #2c4a1e;
font-size: 0.8em;
}

Note: .tour-name is used here as a teaching example. When you style the full STO site in Module 07, the heading class is .tour-card-title and the decorative prefix rule is not included — it is a technique demonstration, not a production rule.

  1. Style form placeholder text — make placeholders visually distinct from entered text:
input::placeholder,
textarea::placeholder {
color: #aaa;
font-style: italic;
}
  1. Optional drop-cap — if your blog article page has a long article intro, add a drop-cap to the first paragraph:
.article-body > p:first-child::first-letter {
font-size: 3.5rem;
float: left;
line-height: 0.75;
margin-right: 0.1em;
color: #2c4a1e;
}

To test this, add class="article-body" to the <div> wrapping your article text in blog-article.html. Note: the full STO stylesheet in Module 07 uses .article-content for this wrapper, not .article-body, and does not include a drop-cap rule — this is a technique demonstration only.

Inspect the result in DevTools. In the Elements panel, expand an element that has ::before or ::after — you will see the pseudo-element listed as a child of the targeted element.

  • Pseudo-elements use :: (double colon) and target a part of an element, not the whole element.
  • ::before and ::after insert generated content; they require the content property.
  • An empty content: "" creates an invisible box — add dimensions and display: block to make it visible.
  • ::first-line and ::first-letter target typographic parts of block content.
  • ::placeholder styles the placeholder text in form inputs.
  • Single-colon syntax (:before) is legacy — use :: in new code.