CSS ::before and ::after: The Complete Practical Guide
Master CSS pseudo-elements for decorative lines, badges, tooltips, custom list markers, overlay effects and more. Includes 10 real UI patterns you can drop into any project.
CSS pseudo-elements are one of those features that separate developers who write a lot of HTML from those who write very little. ::before and ::after let you attach styled content to an element without touching the markup.
Every element has two pseudo-elements available: ::before (inserted before the content) and ::after (inserted after). They require a content property to exist:
.badge::after {
content: 'New';
background: #e8a020;
color: #000;
font-size: 10px;
padding: 2px 6px;
border-radius: 100px;
margin-left: 8px;
vertical-align: middle;
}
content can be a string, empty string (""), attr(), or a counter. For decorative shapes, use an empty string and position absolutely.
.section-title {
position: relative;
display: inline-block;
}
.section-title::after {
content: '';
position: absolute;
bottom: -6px;
left: 0;
width: 40px;
height: 3px;
background: var(--accent);
border-radius: 2px;
}
.card {
position: relative;
overflow: hidden;
}
.card::before {
content: '';
position: absolute;
inset: 0;
background: rgba(232,160,32,0.15);
opacity: 0;
transition: opacity 0.2s;
z-index: 1;
}
.card:hover::before { opacity: 1; }
blockquote {
position: relative;
padding: 16px 24px 16px 48px;
}
blockquote::before {
content: 'C'; /* opening double quote */
position: absolute;
left: 8px;
top: 0;
font-size: 64px;
line-height: 1;
color: var(--accent);
font-family: Georgia, serif;
opacity: 0.6;
}
[data-tooltip] { position: relative; }
[data-tooltip]::after {
content: attr(data-tooltip);
position: absolute;
bottom: calc(100% + 6px);
left: 50%;
transform: translateX(-50%);
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 6px;
padding: 4px 10px;
font-size: 12px;
white-space: nowrap;
pointer-events: none;
opacity: 0;
transition: opacity 0.15s;
}
[data-tooltip]:hover::after { opacity: 1; }
The attr(data-tooltip) function pulls the content directly from the HTML attribute — no JavaScript needed for simple tooltips.