::before and ::after β¨
Create decorative elements, icons, and complex effects without adding extra HTML markup using CSS pseudo-elements.
What are ::before and ::after?
::before and ::after are CSS pseudo-elements that allow you to insert content before or after an element's actual content. They're incredibly powerful for adding decorative elements, icons, and complex visual effects without cluttering your HTML.
π¨ Decorative Elements
Icons, quotes, borders, and backgrounds
π Content Injection
Add text, counters, and dynamic content
β‘ No Extra HTML
Pure CSS solutions for visual enhancements
Basic ::before and ::after Examples
Key Syntax:
element::before { content: ''; }- Inserts before contentelement::after { content: ''; }- Inserts after contentcontentproperty is required- Use
content: ""for empty decorative elements - Pseudo-elements are inline by default
Basic Implementation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Basic ::before and ::after Demo</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', sans-serif;
line-height: 1.6;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 2rem;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 20px;
padding: 3rem;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
h1 {
color: #2d3748;
margin-bottom: 2rem;
text-align: center;
font-size: 2.5rem;
}
.demo-section {
background: #f8fafc;
padding: 2rem;
border-radius: 15px;
margin: 2rem 0;
border-left: 4px solid #667eea;
}
.code-example {
background: #2d3748;
color: #81e6d9;
padding: 1rem;
border-radius: 8px;
font-family: monospace;
margin: 1rem 0;
font-size: 0.9rem;
}
/* Basic ::before and ::after Examples */
.icon-list {
list-style: none;
margin: 2rem 0;
}
.icon-list li {
padding: 1rem;
margin: 0.5rem 0;
background: white;
border-radius: 8px;
border-left: 4px solid #667eea;
}
.icon-list li::before {
content: "π";
margin-right: 1rem;
font-size: 1.2rem;
}
.quote {
background: #e3f2fd;
padding: 2rem;
border-radius: 12px;
margin: 2rem 0;
position: relative;
font-style: italic;
font-size: 1.2rem;
}
.quote::before {
content: "β";
font-size: 4rem;
color: #2196f3;
position: absolute;
top: -10px;
left: 20px;
opacity: 0.3;
}
.quote::after {
content: "β";
font-size: 4rem;
color: #2196f3;
position: absolute;
bottom: -30px;
right: 20px;
opacity: 0.3;
}
/* Decorative Elements */
.fancy-heading {
text-align: center;
margin: 2rem 0;
position: relative;
padding: 1rem 0;
}
.fancy-heading::before,
.fancy-heading::after {
content: "";
position: absolute;
top: 50%;
width: 30%;
height: 2px;
background: linear-gradient(90deg, transparent, #667eea, transparent);
}
.fancy-heading::before {
left: 0;
}
.fancy-heading::after {
right: 0;
}
/* Tooltip Example */
.tooltip-element {
display: inline-block;
background: #667eea;
color: white;
padding: 1rem 2rem;
border-radius: 8px;
margin: 1rem;
position: relative;
cursor: pointer;
}
.tooltip-element::after {
content: attr(data-tooltip);
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
background: #333;
color: white;
padding: 0.5rem 1rem;
border-radius: 4px;
font-size: 0.9rem;
white-space: nowrap;
opacity: 0;
transition: all 0.3s ease;
pointer-events: none;
}
.tooltip-element:hover::after {
opacity: 1;
bottom: 120%;
}
/* Numbered List */
.numbered-list {
counter-reset: step-counter;
margin: 2rem 0;
}
.numbered-list li {
padding: 1rem;
margin: 1rem 0;
background: white;
border-radius: 8px;
border-left: 4px solid #4caf50;
position: relative;
padding-left: 4rem;
}
.numbered-list li::before {
counter-increment: step-counter;
content: counter(step-counter);
position: absolute;
left: 1rem;
top: 50%;
transform: translateY(-50%);
width: 2rem;
height: 2rem;
background: #4caf50;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
}
/* Custom Bullets */
.custom-bullets {
list-style: none;
margin: 2rem 0;
}
.custom-bullets li {
padding: 0.5rem 0;
padding-left: 2rem;
position: relative;
}
.custom-bullets li::before {
content: "";
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 12px;
height: 12px;
background: #ff6b6b;
border-radius: 50%;
border: 2px solid #ff5252;
}
.custom-bullets li:nth-child(2n)::before {
background: #4ecdc4;
border-color: #26a69a;
}
.custom-bullets li:nth-child(3n)::before {
background: #ffe66d;
border-color: #ffd740;
}
</style>
</head>
<body>
<div class="container">
<h1>β¨ ::before and ::after Pseudo-Elements</h1>
<div class="demo-section">
<h2 class="fancy-heading">Basic Icons with ::before</h2>
<div class="code-example">
li::before {<br>
content: "π";<br>
margin-right: 1rem;<br>
}
</div>
<ul class="icon-list">
<li>Add icons to list items</li>
<li>No extra HTML required</li>
<li>Easy to maintain and change</li>
<li>Perfect for UI elements</li>
</ul>
</div>
<div class="demo-section">
<h2 class="fancy-heading">Decorative Quotes</h2>
<div class="code-example">
.quote::before { content: "β"; }<br>
.quote::after { content: "β"; }
</div>
<div class="quote">
This is a beautiful quote that uses ::before and ::after pseudo-elements
to add decorative quotation marks without any extra HTML markup.
</div>
</div>
<div class="demo-section">
<h2 class="fancy-heading">Tooltip with ::after</h2>
<div class="code-example">
.tooltip::after {<br>
content: attr(data-tooltip);<br>
position: absolute;<br>
/* tooltip styling */<br>
}
</div>
<div class="tooltip-element" data-tooltip="This is a cool tooltip!">
Hover over me
</div>
<div class="tooltip-element" data-tooltip="Another tooltip example">
Me too!
</div>
</div>
<div class="demo-section">
<h2 class="fancy-heading">Numbered List with Counters</h2>
<div class="code-example">
.numbered-list { counter-reset: step-counter; }<br>
li::before {<br>
counter-increment: step-counter;<br>
content: counter(step-counter);<br>
}
</div>
<ol class="numbered-list">
<li>First step in the process</li>
<li>Second step with more details</li>
<li>Third step for completion</li>
<li>Final step to finish</li>
</ol>
</div>
<div class="demo-section">
<h2 class="fancy-heading">Custom Bullet Points</h2>
<div class="code-example">
li::before {<br>
content: "";<br>
width: 12px;<br>
height: 12px;<br>
background: #ff6b6b;<br>
border-radius: 50%;<br>
}
</div>
<ul class="custom-bullets">
<li>Custom colored bullets</li>
<li>Different colors for even items</li>
<li>Another custom bullet point</li>
<li>Yellow for every third item</li>
<li>Back to red color</li>
<li>Teal for even items</li>
</ul>
</div>
</div>
</body>
</html>Creative Effects and Animations
Hover Effects
Create interactive hover states with borders, overlays, and animations using pseudo-elements.
Complex Shapes
Build speech bubbles, ribbons, and other complex shapes without images or extra HTML.
Creative Effects Demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Creative ::before and ::after Effects</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', sans-serif;
line-height: 1.6;
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
min-height: 100vh;
padding: 2rem;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 20px;
padding: 3rem;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
h1 {
color: #2d3748;
margin-bottom: 2rem;
text-align: center;
font-size: 2.5rem;
}
.demo-section {
background: #f8fafc;
padding: 2rem;
border-radius: 15px;
margin: 2rem 0;
border-left: 4px solid #4facfe;
}
.code-example {
background: #2d3748;
color: #81e6d9;
padding: 1rem;
border-radius: 8px;
font-family: monospace;
margin: 1rem 0;
font-size: 0.9rem;
}
/* Creative Effects Grid */
.effects-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin: 2rem 0;
}
.effect-card {
background: white;
padding: 2rem;
border-radius: 12px;
text-align: center;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
position: relative;
overflow: hidden;
}
/* Hover Effect with Double Border */
.hover-border {
padding: 2rem;
border: 2px solid #4facfe;
position: relative;
transition: all 0.3s ease;
cursor: pointer;
}
.hover-border::before {
content: "";
position: absolute;
top: -4px;
left: -4px;
right: -4px;
bottom: -4px;
border: 2px solid #ff6b6b;
opacity: 0;
transition: all 0.3s ease;
}
.hover-border:hover::before {
opacity: 1;
top: -8px;
left: -8px;
right: -8px;
bottom: -8px;
}
/* Ribbon Effect */
.ribbon {
position: relative;
background: #4facfe;
color: white;
padding: 2rem;
margin: 2rem 0;
}
.ribbon::before {
content: "";
position: absolute;
top: -10px;
right: -10px;
width: 40px;
height: 40px;
background: #ff6b6b;
transform: rotate(45deg);
z-index: 1;
}
.ribbon::after {
content: "NEW";
position: absolute;
top: 5px;
right: 5px;
color: white;
font-size: 0.8rem;
font-weight: bold;
z-index: 2;
transform: rotate(45deg);
}
/* Speech Bubble */
.speech-bubble {
background: #e3f2fd;
padding: 2rem;
border-radius: 20px;
position: relative;
margin: 2rem 0;
max-width: 400px;
}
.speech-bubble::after {
content: "";
position: absolute;
bottom: -20px;
left: 50px;
border: 10px solid transparent;
border-top-color: #e3f2fd;
}
/* Gradient Overlay */
.gradient-overlay {
position: relative;
padding: 3rem;
background: #2c3e50;
color: white;
margin: 2rem 0;
overflow: hidden;
}
.gradient-overlay::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(45deg, rgba(255,107,107,0.3), rgba(78,205,196,0.3));
opacity: 0;
transition: opacity 0.3s ease;
}
.gradient-overlay:hover::before {
opacity: 1;
}
/* Animated Underline */
.animated-underline {
display: inline-block;
padding: 1rem 2rem;
font-size: 1.2rem;
color: #2c3e50;
text-decoration: none;
position: relative;
margin: 1rem;
}
.animated-underline::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background: #ff6b6b;
transition: width 0.3s ease;
}
.animated-underline:hover::after {
width: 100%;
}
/* Card with Corner Accents */
.corner-card {
position: relative;
padding: 2rem;
background: white;
border: 2px solid #e0e0e0;
margin: 2rem 0;
}
.corner-card::before,
.corner-card::after {
content: "";
position: absolute;
width: 20px;
height: 20px;
background: #4facfe;
}
.corner-card::before {
top: -2px;
left: -2px;
}
.corner-card::after {
bottom: -2px;
right: -2px;
}
/* Pulse Animation */
.pulse-effect {
display: inline-block;
padding: 2rem;
background: #4caf50;
color: white;
border-radius: 50%;
margin: 2rem;
position: relative;
}
.pulse-effect::before {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
border: 2px solid #4caf50;
border-radius: 50%;
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { transform: scale(1); opacity: 1; }
100% { transform: scale(1.5); opacity: 0; }
}
/* Stacked Effect */
.stacked {
position: relative;
padding: 2rem;
background: #ffe66d;
margin: 2rem 0;
transform: rotate(-1deg);
}
.stacked::before {
content: "";
position: absolute;
top: 5px;
left: 5px;
right: -5px;
bottom: -5px;
background: #ffd740;
z-index: -1;
transform: rotate(1deg);
}
.stacked::after {
content: "";
position: absolute;
top: 10px;
left: 10px;
right: -10px;
bottom: -10px;
background: #ffc400;
z-index: -2;
transform: rotate(2deg);
}
</style>
</head>
<body>
<div class="container">
<h1>π¨ Creative ::before and ::after Effects</h1>
<div class="demo-section">
<h2>Hover Border Effect</h2>
<div class="code-example">
.element::before {<br>
border: 2px solid #ff6b6b;<br>
opacity: 0;<br>
transition: all 0.3s ease;<br>
}<br>
.element:hover::before {<br>
opacity: 1;<br>
/* expand border */<br>
}
</div>
<div class="effects-grid">
<div class="effect-card">
<div class="hover-border">
<h3>Hover Over Me</h3>
<p>Watch the double border appear</p>
</div>
</div>
</div>
</div>
<div class="demo-section">
<h2>Ribbon Badge</h2>
<div class="code-example">
.ribbon::before {<br>
content: "";<br>
position: absolute;<br>
top: -10px; right: -10px;<br>
width: 40px; height: 40px;<br>
background: #ff6b6b;<br>
transform: rotate(45deg);<br>
}<br>
.ribbon::after {<br>
content: "NEW";<br>
/* positioning and styling */<br>
}
</div>
<div class="ribbon">
<h3>Featured Content</h3>
<p>This card has a beautiful ribbon badge</p>
</div>
</div>
<div class="demo-section">
<h2>Speech Bubble</h2>
<div class="code-example">
.speech-bubble::after {<br>
content: "";<br>
position: absolute;<br>
bottom: -20px;<br>
border: 10px solid transparent;<br>
border-top-color: #e3f2fd;<br>
}
</div>
<div class="speech-bubble">
<p>Hello! I'm a speech bubble created with ::after pseudo-element!</p>
</div>
</div>
<div class="demo-section">
<h2>Gradient Overlay on Hover</h2>
<div class="code-example">
.gradient-overlay::before {<br>
content: "";<br>
background: linear-gradient(45deg, rgba(255,107,107,0.3), rgba(78,205,196,0.3));<br>
opacity: 0;<br>
transition: opacity 0.3s ease;<br>
}<br>
.gradient-overlay:hover::before {<br>
opacity: 1;<br>
}
</div>
<div class="gradient-overlay">
<h3>Hover for Gradient</h3>
<p>Move your mouse over this box to see the gradient overlay</p>
</div>
</div>
<div class="demo-section">
<h2>Animated Underline</h2>
<div class="code-example">
.animated-underline::after {<br>
content: "";<br>
position: absolute;<br>
bottom: 0; left: 0;<br>
width: 0; height: 2px;<br>
transition: width 0.3s ease;<br>
}<br>
.animated-underline:hover::after {<br>
width: 100%;<br>
}
</div>
<div style="text-align: center;">
<a href="#" class="animated-underline">Home</a>
<a href="#" class="animated-underline">About</a>
<a href="#" class="animated-underline">Services</a>
<a href="#" class="animated-underline">Contact</a>
</div>
</div>
<div class="demo-section">
<h2>Pulse Animation Effect</h2>
<div class="code-example">
.pulse-effect::before {<br>
content: "";<br>
border: 2px solid #4caf50;<br>
animation: pulse 2s infinite;<br>
}<br>
@keyframes pulse {<br>
0% { transform: scale(1); opacity: 1; }<br>
100% { transform: scale(1.5); opacity: 0; }<br>
}
</div>
<div style="text-align: center;">
<div class="pulse-effect">π</div>
</div>
</div>
<div class="demo-section">
<h2>Stacked Paper Effect</h2>
<div class="code-example">
.stacked::before, .stacked::after {<br>
content: "";<br>
position: absolute;<br>
background: different shades;<br>
transform: rotate(slightly);<br>
z-index: -1;<br>
}
</div>
<div class="stacked">
<h3>Stacked Note</h3>
<p>This creates a nice 3D stacked paper effect</p>
</div>
</div>
</div>
</body>
</html>Practical Real-World Examples
π Breadcrumbs
Navigation separators and icons
β Custom Forms
Checkboxes, radio buttons, and validation
π UI Components
Badges, tooltips, and progress indicators
Practical Implementation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Practical ::before and ::after Examples</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', sans-serif;
line-height: 1.6;
background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);
min-height: 100vh;
padding: 2rem;
}
.container {
max-width: 1400px;
margin: 0 auto;
}
h1 {
color: #2d3748;
margin-bottom: 2rem;
text-align: center;
font-size: 2.5rem;
}
/* Practical Examples Grid */
.practical-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
gap: 2rem;
margin: 2rem 0;
}
.example-card {
background: white;
border-radius: 15px;
padding: 2rem;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
/* Breadcrumb Navigation */
.breadcrumb {
display: flex;
list-style: none;
padding: 1rem;
background: #f8f9fa;
border-radius: 8px;
margin: 1rem 0;
}
.breadcrumb li {
margin-right: 0.5rem;
}
.breadcrumb li:not(:last-child)::after {
content: "βΊ";
margin-left: 0.5rem;
color: #6c757d;
}
.breadcrumb a {
text-decoration: none;
color: #007bff;
}
.breadcrumb a:hover {
text-decoration: underline;
}
/* Custom Checkboxes */
.checkbox-group {
margin: 1rem 0;
}
.custom-checkbox {
position: relative;
padding-left: 2rem;
margin: 0.5rem 0;
cursor: pointer;
}
.custom-checkbox input {
position: absolute;
opacity: 0;
}
.custom-checkbox .checkmark {
position: absolute;
left: 0;
top: 0;
height: 1.2rem;
width: 1.2rem;
background: #e9ecef;
border-radius: 3px;
transition: all 0.3s;
}
.custom-checkbox input:checked + .checkmark {
background: #007bff;
}
.custom-checkbox input:checked + .checkmark::after {
content: "β";
color: white;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
/* Price Tag */
.price-tag {
display: inline-block;
background: #28a745;
color: white;
padding: 0.5rem 1rem;
border-radius: 4px;
position: relative;
margin: 1rem 0;
}
.price-tag::before {
content: "";
position: absolute;
right: -10px;
top: 50%;
transform: translateY(-50%);
border: 10px solid transparent;
border-left-color: #28a745;
}
/* Notification Badge */
.notification-icon {
position: relative;
display: inline-block;
background: #6c757d;
color: white;
padding: 1rem;
border-radius: 50%;
margin: 1rem;
}
.notification-icon::after {
content: "3";
position: absolute;
top: -5px;
right: -5px;
background: #dc3545;
color: white;
width: 20px;
height: 20px;
border-radius: 50%;
font-size: 0.8rem;
display: flex;
align-items: center;
justify-content: center;
}
/* Loading Spinner */
.spinner {
width: 40px;
height: 40px;
border: 4px solid #e9ecef;
border-top: 4px solid #007bff;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 1rem auto;
position: relative;
}
.spinner::before {
content: "";
position: absolute;
top: -4px;
left: -4px;
right: -4px;
bottom: -4px;
border: 4px solid transparent;
border-top: 4px solid #6f42c1;
border-radius: 50%;
animation: spin 1.5s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Step Progress Bar */
.progress-steps {
display: flex;
margin: 2rem 0;
position: relative;
}
.progress-steps::before {
content: "";
position: absolute;
top: 15px;
left: 0;
right: 0;
height: 2px;
background: #e9ecef;
z-index: 1;
}
.step {
flex: 1;
text-align: center;
position: relative;
z-index: 2;
}
.step::before {
content: "";
width: 30px;
height: 30px;
background: #e9ecef;
border-radius: 50%;
display: block;
margin: 0 auto 0.5rem;
position: relative;
z-index: 2;
}
.step.active::before {
background: #007bff;
}
.step.completed::before {
background: #28a745;
content: "β";
color: white;
display: flex;
align-items: center;
justify-content: center;
}
/* Custom Blockquote */
.blockquote {
background: #f8f9fa;
padding: 2rem;
border-left: 4px solid #007bff;
margin: 1rem 0;
position: relative;
font-style: italic;
}
.blockquote::before {
content: "β";
font-size: 3rem;
color: #007bff;
position: absolute;
top: -10px;
left: 10px;
opacity: 0.3;
}
.blockquote::after {
content: "β";
font-size: 3rem;
color: #007bff;
position: absolute;
bottom: -30px;
right: 10px;
opacity: 0.3;
}
/* Code Block with Copy Button */
.code-block {
background: #2d3748;
color: #81e6d9;
padding: 1rem;
border-radius: 8px;
margin: 1rem 0;
position: relative;
font-family: monospace;
}
.code-block::after {
content: "Copy";
position: absolute;
top: 0.5rem;
right: 0.5rem;
background: #4a5568;
color: white;
padding: 0.2rem 0.5rem;
border-radius: 3px;
font-size: 0.8rem;
cursor: pointer;
}
/* Feature List with Icons */
.feature-list {
list-style: none;
margin: 1rem 0;
}
.feature-list li {
padding: 0.5rem 0;
padding-left: 2rem;
position: relative;
}
.feature-list li::before {
content: "β";
position: absolute;
left: 0;
top: 0.5rem;
width: 1.2rem;
height: 1.2rem;
background: #28a745;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.8rem;
}
</style>
</head>
<body>
<div class="container">
<h1>πΌ Practical ::before and ::after Examples</h1>
<div class="practical-grid">
<!-- Breadcrumb Navigation -->
<div class="example-card">
<h2>π Breadcrumb Navigation</h2>
<nav>
<ul class="breadcrumb">
<li><a href="#">Home</a></li>
<li><a href="#">Products</a></li>
<li><a href="#">Electronics</a></li>
<li>Smartphones</li>
</ul>
</nav>
<p>Uses <code>::after</code> for separators between breadcrumb items</p>
</div>
<!-- Custom Checkboxes -->
<div class="example-card">
<h2>β
Custom Checkboxes</h2>
<div class="checkbox-group">
<label class="custom-checkbox">
<input type="checkbox" checked>
<span class="checkmark"></span>
Accept Terms and Conditions
</label>
<label class="custom-checkbox">
<input type="checkbox">
<span class="checkmark"></span>
Subscribe to Newsletter
</label>
<label class="custom-checkbox">
<input type="checkbox">
<span class="checkmark"></span>
Enable Notifications
</label>
</div>
<p>Custom checkboxes using <code>::after</code> for checkmarks</p>
</div>
<!-- Price Tag -->
<div class="example-card">
<h2>π° Price Tag</h2>
<div class="price-tag">$29.99</div>
<p>Price tag with arrow using <code>::before</code> for the pointed end</p>
</div>
<!-- Notification Badge -->
<div class="example-card">
<h2>π Notification Badge</h2>
<div class="notification-icon">π§</div>
<div class="notification-icon">π</div>
<p>Notification badges using <code>::after</code> for the counter</p>
</div>
<!-- Loading Spinner -->
<div class="example-card">
<h2>β³ Loading Spinner</h2>
<div class="spinner"></div>
<p>Animated spinner with double border using <code>::before</code></p>
</div>
<!-- Progress Steps -->
<div class="example-card">
<h2>π Progress Steps</h2>
<div class="progress-steps">
<div class="step completed">Sign Up</div>
<div class="step completed">Profile</div>
<div class="step active">Preferences</div>
<div class="step">Confirmation</div>
</div>
<p>Progress indicator using <code>::before</code> for steps and connector line</p>
</div>
</div>
<!-- Additional Examples -->
<div class="example-card" style="margin: 2rem 0;">
<h2>π¬ Custom Blockquote</h2>
<blockquote class="blockquote">
This is an example of a beautifully styled blockquote using ::before and ::after
pseudo-elements for the quotation marks. It adds visual appeal without extra HTML.
</blockquote>
</div>
<div class="example-card" style="margin: 2rem 0;">
<h2>π Feature List</h2>
<ul class="feature-list">
<li>Responsive Design</li>
<li>Fast Performance</li>
<li>Easy Customization</li>
<li>Great Support</li>
<li>Regular Updates</li>
</ul>
<p>Feature list with custom checkmarks using <code>::before</code></p>
</div>
<div class="example-card" style="margin: 2rem 0;">
<h2>π» Code Block with Copy Button</h2>
<div class="code-block">
// Example code<br>
function helloWorld() {<br>
console.log("Hello, World!");<br>
}
</div>
<p>Code block with copy button using <code>::after</code></p>
</div>
</div>
</body>
</html>Advanced Techniques
Complex Layering and Animation
Combine multiple pseudo-elements with CSS animations, transforms, and advanced positioning to create sophisticated visual effects and interactions.
Advanced Techniques Demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Advanced ::before and ::after Techniques</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', sans-serif;
line-height: 1.6;
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
min-height: 100vh;
padding: 2rem;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 20px;
padding: 3rem;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
h1 {
color: #2d3748;
margin-bottom: 2rem;
text-align: center;
font-size: 2.5rem;
}
.demo-section {
background: #f8fafc;
padding: 2rem;
border-radius: 15px;
margin: 2rem 0;
border-left: 4px solid #a8edea;
}
.code-example {
background: #2d3748;
color: #81e6d9;
padding: 1rem;
border-radius: 8px;
font-family: monospace;
margin: 1rem 0;
font-size: 0.9rem;
}
/* Advanced Techniques */
.advanced-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 2rem;
margin: 2rem 0;
}
.technique-card {
background: white;
padding: 2rem;
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
/* Multiple Background Layers */
.layered-background {
padding: 3rem;
margin: 2rem 0;
position: relative;
background: #2c3e50;
color: white;
overflow: hidden;
}
.layered-background::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(45deg, rgba(255,107,107,0.2), rgba(78,205,196,0.2));
z-index: 1;
}
.layered-background::after {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="2" fill="white" opacity="0.1"/></svg>');
z-index: 2;
}
.layered-background > * {
position: relative;
z-index: 3;
}
/* Complex Shape Creation */
.speech-bubble-advanced {
background: #e3f2fd;
padding: 2rem;
border-radius: 20px;
position: relative;
margin: 2rem 0;
max-width: 400px;
}
.speech-bubble-advanced::before {
content: "";
position: absolute;
bottom: -20px;
left: 50px;
border: 10px solid transparent;
border-top-color: #e3f2fd;
}
.speech-bubble-advanced::after {
content: "";
position: absolute;
bottom: -15px;
left: 55px;
border: 8px solid transparent;
border-top-color: #e3f2fd;
filter: brightness(0.9);
}
/* Animated Gradient Border */
.gradient-border {
padding: 2rem;
margin: 2rem 0;
position: relative;
background: white;
border-radius: 8px;
}
.gradient-border::before {
content: "";
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
background: linear-gradient(45deg, #ff6b6b, #4ecdc4, #45b7d1, #96ceb4);
border-radius: 10px;
z-index: -1;
animation: gradientMove 3s ease infinite;
background-size: 400% 400%;
}
@keyframes gradientMove {
0%, 100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
}
/* 3D Transform Effects */
.card-3d {
padding: 2rem;
margin: 2rem 0;
background: white;
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
position: relative;
transform-style: preserve-3d;
perspective: 1000px;
}
.card-3d::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(45deg, #667eea, #764ba2);
border-radius: 12px;
transform: translateZ(-10px);
opacity: 0.1;
transition: all 0.3s ease;
}
.card-3d:hover::before {
transform: translateZ(-5px);
opacity: 0.2;
}
/* Custom Cursor */
.custom-cursor-area {
padding: 3rem;
margin: 2rem 0;
background: #2c3e50;
color: white;
border-radius: 12px;
position: relative;
overflow: hidden;
cursor: none;
}
.custom-cursor-area::before {
content: "";
position: absolute;
width: 20px;
height: 20px;
background: #ff6b6b;
border-radius: 50%;
pointer-events: none;
transform: translate(-50%, -50%);
transition: all 0.1s ease;
z-index: 1000;
}
.custom-cursor-area:hover::before {
transform: translate(-50%, -50%) scale(1.5);
background: #4ecdc4;
}
/* Text Effects */
.fancy-text {
font-size: 3rem;
font-weight: bold;
text-align: center;
margin: 2rem 0;
position: relative;
background: linear-gradient(45deg, #ff6b6b, #4ecdc4);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.fancy-text::before {
content: attr(data-text);
position: absolute;
top: 2px;
left: 2px;
background: linear-gradient(45deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
z-index: -1;
filter: blur(2px);
}
.fancy-text::after {
content: attr(data-text);
position: absolute;
top: -2px;
left: -2px;
background: linear-gradient(45deg, #ffe66d, #ffa726);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
z-index: -2;
filter: blur(4px);
opacity: 0.5;
}
/* Interactive Demo Controls */
.demo-controls {
background: #fff3e0;
padding: 1rem;
border-radius: 8px;
margin: 1rem 0;
border-left: 4px solid #ff9800;
}
/* Responsive Adjustments */
@media (max-width: 768px) {
.advanced-grid {
grid-template-columns: 1fr;
}
.fancy-text {
font-size: 2rem;
}
}
</style>
</head>
<body>
<div class="container">
<h1>π Advanced ::before and ::after Techniques</h1>
<div class="demo-section">
<h2>Layered Background Effects</h2>
<div class="code-example">
.element::before {<br>
/* Gradient overlay */<br>
background: linear-gradient(...);<br>
z-index: 1;<br>
}<br>
.element::after {<br>
/* Pattern overlay */<br>
background: url(...);<br>
z-index: 2;<br>
}<br>
.element > * { z-index: 3; }
</div>
<div class="layered-background">
<h3>Multi-Layered Background</h3>
<p>This element uses multiple pseudo-elements to create complex background effects with gradient and pattern overlays.</p>
</div>
</div>
<div class="demo-section">
<h2>Advanced Speech Bubble</h2>
<div class="code-example">
.speech-bubble::before {<br>
/* Main triangle */<br>
border: 10px solid transparent;<br>
border-top-color: #e3f2fd;<br>
}<br>
.speech-bubble::after {<br>
/* Secondary triangle for depth */<br>
border: 8px solid transparent;<br>
border-top-color: #e3f2fd;<br>
filter: brightness(0.9);<br>
}
</div>
<div class="speech-bubble-advanced">
<p>This speech bubble uses both ::before and ::after to create a more realistic 3D effect with shadow depth.</p>
</div>
</div>
<div class="demo-section">
<h2>Animated Gradient Border</h2>
<div class="code-example">
.gradient-border::before {<br>
background: linear-gradient(45deg, #ff6b6b, #4ecdc4, #45b7d1, #96ceb4);<br>
animation: gradientMove 3s ease infinite;<br>
background-size: 400% 400%;<br>
}<br>
@keyframes gradientMove {<br>
0%, 100% { background-position: 0% 50%; }<br>
50% { background-position: 100% 50%; }<br>
}
</div>
<div class="gradient-border">
<h3>Moving Gradient Border</h3>
<p>This card has an animated gradient border that continuously moves around the element.</p>
</div>
</div>
<div class="demo-section">
<h2>3D Card Effect</h2>
<div class="code-example">
.card-3d::before {<br>
transform: translateZ(-10px);<br>
transition: all 0.3s ease;<br>
}<br>
.card-3d:hover::before {<br>
transform: translateZ(-5px);<br>
}
</div>
<div class="card-3d">
<h3>3D Depth Effect</h3>
<p>Hover over this card to see the 3D depth effect created with CSS transforms and pseudo-elements.</p>
</div>
</div>
<div class="demo-section">
<h2>Custom Cursor</h2>
<div class="code-example">
.custom-cursor-area {<br>
cursor: none;<br>
}<br>
.custom-cursor-area::before {<br>
/* Custom cursor */<br>
pointer-events: none;<br>
transform: translate(-50%, -50%);<br>
}
</div>
<div class="custom-cursor-area">
<h3>Custom Cursor Area</h3>
<p>Move your mouse over this area to see the custom cursor replacement. The cursor is created using ::before pseudo-element.</p>
<p><small>Note: This is a simple demo. For production, consider accessibility implications.</small></p>
</div>
</div>
<div class="demo-section">
<h2>Multi-Layered Text Effects</h2>
<div class="code-example">
.fancy-text::before {<br>
content: attr(data-text);<br>
/* Offset shadow layer */<br>
filter: blur(2px);<br>
}<br>
.fancy-text::after {<br>
content: attr(data-text);<br>
/* Second shadow layer */<br>
filter: blur(4px);<br>
opacity: 0.5;<br>
}
</div>
<div class="fancy-text" data-text="GLOWING TEXT">GLOWING TEXT</div>
</div>
<div class="demo-controls">
<h3>π‘ Pro Tips for Advanced Usage</h3>
<ul>
<li>Use <code>z-index</code> to control stacking order of multiple pseudo-elements</li>
<li>Combine with CSS variables for dynamic styling</li>
<li>Use <code>attr()</code> function to make content dynamic</li>
<li>Consider performance when using multiple animated pseudo-elements</li>
<li>Test across browsers for consistent rendering</li>
<li>Use <code>pointer-events: none</code> for interactive pseudo-elements</li>
</ul>
</div>
</div>
<script>
// Custom cursor movement
document.addEventListener('mousemove', function(e) {
const cursorArea = document.querySelector('.custom-cursor-area');
if (cursorArea && cursorArea.matches(':hover')) {
const pseudo = getComputedStyle(cursorArea, '::before');
cursorArea.style.setProperty('--cursor-x', e.clientX + 'px');
cursorArea.style.setProperty('--cursor-y', e.clientY + 'px');
}
});
</script>
</body>
</html>Best Practices & Common Pitfalls
β Do This
- Always include the
contentproperty - Use
content: ""for decorative elements - Set
displayproperty when needed - Use for purely presentational content
- Consider accessibility with screen readers
- Test in multiple browsers
β Avoid This
- Don't use for important content
- Avoid complex content that needs selection
- Don't forget to set
content - Avoid overusing for simple decorations
- Don't rely on for critical functionality
- Avoid complex animations on many elements
π― When to Use Pseudo-Elements
Good Uses:
- Decorative icons and symbols
- Custom bullets and numbering
- Visual effects and overlays
- Tooltips and speech bubbles
- Form element enhancements
Avoid For:
- Important textual content
- Interactive elements that need focus
- Content that should be selectable
- SEO-critical information
- Complex layout structures
Browser Support & Accessibility
Compatibility Overview
Accessibility Considerations
Pseudo-element content is generally not accessible to screen readers. Use them for decorative purposes only, and ensure important content is present in the actual HTML.
Ready to Create Magic? β¨
Experiment with our comprehensive examples and discover the creative power of ::before and ::after pseudo-elements. Enhance your designs with pure CSS!