Pseudo-elements
::before, ::after, ::first-line, ::placeholder.
Pseudo-elements are one of CSS's most powerful features. They let you add decorative content, style text fragments, and create visual effects that would otherwise require extra HTML elements.
::before and ::after
::before inserts generated content before an element's content. ::after inserts it after. Both require a content property — even if it's empty.
.quote::before {
content: "\201C"; /* opening curly quote */
color: #6367ff;
font-size: 1.5em;
}
.quote::after {
content: "\201D"; /* closing curly quote */
color: #6367ff;
font-size: 1.5em;
}
Decorative Effects with ::before and ::after
A common use is creating decorative shapes or underlines without extra markup:
/* Animated underline on hover */
.link {
position: relative;
text-decoration: none;
}
.link::after {
content: "";
position: absolute;
bottom: -2px;
left: 0;
width: 0;
height: 2px;
background: #6367ff;
transition: width 200ms ease;
}
.link:hover::after {
width: 100%;
}
/* Accent dot before a list item */
.feature-item::before {
content: "";
display: inline-block;
width: 6px;
height: 6px;
background: #6367ff;
border-radius: 50%;
margin-right: 8px;
vertical-align: middle;
}
When content: "" is set and the pseudo-element is positioned absolutely, it becomes a blank canvas you can size and style freely — no extra HTML needed.
::first-line and ::first-letter
/* Style just the first line of a paragraph */
p::first-line {
font-weight: 600;
color: #0f172a;
}
/* Drop cap effect */
.article p:first-child::first-letter {
font-size: 3rem;
font-weight: 900;
float: left;
line-height: 1;
margin-right: 0.1em;
color: #6367ff;
}
::placeholder
Style the placeholder text inside form inputs:
input::placeholder {
color: #94a3b8;
font-style: italic;
}
input:focus::placeholder {
color: #cbd5e1;
}
::selection
Style the text highlight when a user selects text on the page:
::selection {
background-color: #6367ff;
color: white;
}
::marker
Style the bullet points or numbers of list items:
li::marker {
color: #6367ff;
font-weight: bold;
}
Pseudo-elements vs Pseudo-classes
It's easy to confuse the two. Remember:
- Pseudo-elements (double colon
::) — target a part of an element:::before,::after,::first-line - Pseudo-classes (single colon
:) — target an element in a certain state::hover,:focus,:nth-child()
Have anything to say about this lesson?
Your feedback helps improve these tutorials. If something was confusing or missing, let us know.