Pseudo-Elements: Decorative Shapes and Sub-Element Styling
Master CSS Pseudo-Elements. Learn how to generate content using ::before and ::after, style first letters, and customize selection highlights.
Introduction
If you want to add a small arrow symbol ($\rightarrow$) next to every link on your page, you could manually type the character inside every HTML tag. However, if you ever want to change that arrow to a chevron, you have to modify dozens of pages.
In CSS, Pseudo-Elements solve this by letting you create decorative styles and insert content programmatically without altering the HTML structure. Marked by a double colon (::), pseudo-elements target specific parts of an element, such as its first letter, its first line, or generated slots placed before or after its content.
What You Will Learn
- The difference between Pseudo-Classes (
:) and Pseudo-Elements (::). - How to generate content using
::beforeand::after. - Formatting drop caps using
::first-letterand::first-line. - Customizing browser highlight colors using
::selection.
Prerequisites
Detailed Explanation: Sub-Element Selectors
A pseudo-element is appended to a selector using double colons: selector::pseudo-element.
- Note: While older browsers support a single colon (e.g.
:before), the W3C introduced the double-colon syntax (::before) in CSS3 to clearly distinguish pseudo-elements from pseudo-classes.
The Power of ::before and ::after
These two pseudo-elements inject virtual child elements before or after the targeted element's actual content.
- The Content Property: For
::beforeand::afterto render at all, you must declare thecontentproperty, even if it is just an empty string (content: "";). - These are widely used to add decorative icons, underline animations, and background shape overlays without polluting the HTML markup.
Key Pseudo-Elements
| Pseudo-Element | Targets | Use Case |
| :--- | :--- | :--- |
| ::before | A virtual child before the content. | Adding icons, bullet custom shapes. |
| ::after | A virtual child after the content. | Adding arrow indicators, line wraps. |
| ::first-letter| The first character of block text. | Designing a large drop cap. |
| ::selection | Text highlighted by the user's cursor. | Customizing selection background color. |
Visual Learning Diagram (Mermaid)
graph LR
subgraph HTML element rendering
BE[::before pseudo-element] -->|Appends| C[Actual Text Content]
C -->|Appends| AE[::after pseudo-element]
end
Code Examples
Example 1: Animated Button Underline
Let's build an interactive menu link with a sliding underline animation using ::after:
/* Base link styling */
.nav-link {
color: #f8fafc;
text-decoration: none;
position: relative; /* Anchor for pseudo-element positioning */
padding-bottom: 5px;
}
/* Create the underline element using ::after */
.nav-link::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 0%; /* Initial width is zero */
height: 2px;
background-color: #38bdf8; /* Blue underline */
transition: width 0.3s ease; /* Smooth hover transition */
}
/* Slide in the underline on hover */
.nav-link:hover::after {
width: 100%;
}
Example 2: Drop Caps and Text Highlight
Style paragraphs like a classic magazine drop cap and customize highlight selections:
/* Style the first letter */
.blog-post::first-letter {
font-size: 3rem;
font-weight: bold;
color: #3b82f6;
float: left;
margin-right: 8px;
line-height: 1;
}
/* Customize text selection highlights */
::selection {
background-color: rgba(56, 189, 248, 0.3); /* Transparent sky-blue */
color: #ffffff;
}
Summary
Pseudo-elements target specific segments of elements using double-colon (::) notation. By utilizing ::before and ::after accompanied by the content property, developers generate structural design layers, and use selection highlight overrides to create premium user interfaces.
Related Articles
Next Tutorial
If multiple class, element, and pseudo-selectors target the same paragraph, how does the browser calculate which style wins? Let's check: Selector Specificity.