::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 contentcontent
property 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
content
property - Use
content: ""
for decorative elements - Set
display
property 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!