CSS Tutorial
CSS Pseudo-element
::before, ::after, and ::first-line insert extra boxes or style a slice of text.
Two colons, an extra piece
A pseudo-element styles a slice of an element, or inserts a box you never wrote in HTML. The modern spelling uses two colons: ::before, ::after,::first-line. Older sheets used one colon. Browsers still accept that for these names. Write two colons so a later reader can tell them apart from :hover.
::before and ::after create real boxes inside the element. They can have background, size, and position. They cannot hold nested HTML. The text they show comes from thecontent property.
| Pseudo-element | What it targets |
|---|---|
::before | A box as the first child, before the real content |
::after | A box as the last child, after the real content |
::first-line | The first wrapped line of a block of text |
::first-letter | The first letter (drop caps); not in this chapter’s examples |
content is required
Without content, ::before and ::after do not draw. An empty stringcontent: "" is valid and common when you only need a colored bar or a circle. A quoted string puts characters on the page. content: none removes the box.
Do not store the only copy of a price, a name, or a warning in content. Assistive tools and search engines often miss it. Keep real words in HTML. Use pseudo-elements for marks, icons, and decoration.
Click Try it in CSS under an example. That opens /css/try.
::before
Harbor studio marks a quote with a teal bar. The bar is not a span in the HTML. It is::before with an empty string, a width, and a background.
Example
<style>
body {
font-family: Georgia, serif;
margin: 1.25rem;
background: #f0f9ff;
color: #0c4a6e;
}
blockquote {
position: relative;
margin: 0;
padding: 0.35rem 0 0.35rem 1.15rem;
font-size: 1.15rem;
}
blockquote::before {
content: "";
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 4px;
background: #0d9488;
border-radius: 2px;
}
</style>
<h1>Harbor studio</h1>
<blockquote>Open 8–16. Tide prints at the desk.</blockquote>The quote still reads if CSS fails. The bar is paint. That is the right split.
::after
::after sits after the content. A units suffix, a decorative dash, or a small “new” mark are typical. Here the hours line adds a sky label after the time.
Example
<style>
body {
font-family: Georgia, serif;
margin: 1.25rem;
background: #f0f9ff;
color: #0c4a6e;
}
.hours {
font-size: 1.2rem;
}
.hours::after {
content: " desk open";
color: #0284c7;
font-size: 0.85rem;
letter-spacing: 0.04em;
text-transform: uppercase;
}
</style>
<h1>Harbor studio</h1>
<p class="hours">8–16</p>Change the string in content and the label updates. If the words matter to the booking, put them in the paragraph instead and style a span.
::first-line
::first-line styles only the first wrapped line of a block. Resize the preview: as the line break moves, the styled slice moves with it. You do not count characters yourself.
Only a short list of properties apply: color, font, background, and a few others. You cannot setmargin or width on ::first-line.
Example
<style>
body {
font-family: Georgia, serif;
margin: 1.25rem;
background: #f0f9ff;
color: #0c4a6e;
}
.blurb {
max-width: 22rem;
line-height: 1.55;
}
.blurb::first-line {
color: #0d9488;
font-weight: 700;
letter-spacing: 0.02em;
}
</style>
<h1>Harbor studio</h1>
<p class="blurb">
Harbor Lane 12 sits above the slip. The morning light hits the north wall first.
Prints dry on the rack by noon. Visitors sign in at the desk.
</p>What to do next
You now have two extra selector kinds: states (:hover) and slices (::before). When two rules still fight, the winner is specificity — ids, classes, elements, and inline styles. That is the next chapter.
Worked examples
The short listings above show one property. These sheets paint documents you would actually ship: a lab dashboard, a clinic form, a marks table, a nav bar.
CSS does not invent meaning. HTML already said what the pieces are. Cascade, specificity, and the box model decide how they look. The numbers are classroom values — current, pH, pulse, 3-4-5 — so the style has something real to sit on.
Preview them in the CSS editor at /css/try. Change one property and watch the page paint. The tags stay the same.
Biology
A live dot before “open”
::before and ::after insert extra boxes. content is required or they do not generate. They are not in the DOM for screen readers in a useful way — keep the real word “open” in the HTML.
::first-line styles a slice of text. It is a flourish, not a heading.
Example
<style>
.open::before { content: "● "; color: #16a34a; }
</style>
<p class="open">Open for walk-ins</p>Maths
An arrow after a proof link
content: " →" is decoration. The link text still has to make sense if the arrow is missing.
Example
<style>
a::after { content: " →"; color: #3730a3; }
</style>
<p><a href="/css">Pythagoras notes</a></p>