::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 content
  • element::after { content: ''; } - Inserts after content
  • content 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>
        &nbsp;&nbsp;content: "πŸ‘‰";<br>
        &nbsp;&nbsp;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>
        &nbsp;&nbsp;content: attr(data-tooltip);<br>
        &nbsp;&nbsp;position: absolute;<br>
        &nbsp;&nbsp;/* 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>
        &nbsp;&nbsp;counter-increment: step-counter;<br>
        &nbsp;&nbsp;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>
        &nbsp;&nbsp;content: "";<br>
        &nbsp;&nbsp;width: 12px;<br>
        &nbsp;&nbsp;height: 12px;<br>
        &nbsp;&nbsp;background: #ff6b6b;<br>
        &nbsp;&nbsp;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.

.element:hover::before {
Β Β opacity: 1;
Β Β transform: scale(1.1);
}

Complex Shapes

Build speech bubbles, ribbons, and other complex shapes without images or extra HTML.

.bubble::after {
Β Β content: "";
Β Β border: 10px solid transparent;
}

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>
        &nbsp;&nbsp;border: 2px solid #ff6b6b;<br>
        &nbsp;&nbsp;opacity: 0;<br>
        &nbsp;&nbsp;transition: all 0.3s ease;<br>
        }<br>
        .element:hover::before {<br>
        &nbsp;&nbsp;opacity: 1;<br>
        &nbsp;&nbsp;/* 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>
        &nbsp;&nbsp;content: "";<br>
        &nbsp;&nbsp;position: absolute;<br>
        &nbsp;&nbsp;top: -10px; right: -10px;<br>
        &nbsp;&nbsp;width: 40px; height: 40px;<br>
        &nbsp;&nbsp;background: #ff6b6b;<br>
        &nbsp;&nbsp;transform: rotate(45deg);<br>
        }<br>
        .ribbon::after {<br>
        &nbsp;&nbsp;content: "NEW";<br>
        &nbsp;&nbsp;/* 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>
        &nbsp;&nbsp;content: "";<br>
        &nbsp;&nbsp;position: absolute;<br>
        &nbsp;&nbsp;bottom: -20px;<br>
        &nbsp;&nbsp;border: 10px solid transparent;<br>
        &nbsp;&nbsp;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>
        &nbsp;&nbsp;content: "";<br>
        &nbsp;&nbsp;background: linear-gradient(45deg, rgba(255,107,107,0.3), rgba(78,205,196,0.3));<br>
        &nbsp;&nbsp;opacity: 0;<br>
        &nbsp;&nbsp;transition: opacity 0.3s ease;<br>
        }<br>
        .gradient-overlay:hover::before {<br>
        &nbsp;&nbsp;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>
        &nbsp;&nbsp;content: "";<br>
        &nbsp;&nbsp;position: absolute;<br>
        &nbsp;&nbsp;bottom: 0; left: 0;<br>
        &nbsp;&nbsp;width: 0; height: 2px;<br>
        &nbsp;&nbsp;transition: width 0.3s ease;<br>
        }<br>
        .animated-underline:hover::after {<br>
        &nbsp;&nbsp;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>
        &nbsp;&nbsp;content: "";<br>
        &nbsp;&nbsp;border: 2px solid #4caf50;<br>
        &nbsp;&nbsp;animation: pulse 2s infinite;<br>
        }<br>
        @keyframes pulse {<br>
        &nbsp;&nbsp;0% { transform: scale(1); opacity: 1; }<br>
        &nbsp;&nbsp;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>
        &nbsp;&nbsp;content: "";<br>
        &nbsp;&nbsp;position: absolute;<br>
        &nbsp;&nbsp;background: different shades;<br>
        &nbsp;&nbsp;transform: rotate(slightly);<br>
        &nbsp;&nbsp;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>
        &nbsp;&nbsp;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.

/* Multiple pseudo-elements */
.element::before
.element::after
/* With animations */
@keyframes slideIn {...}

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>
        &nbsp;&nbsp;/* Gradient overlay */<br>
        &nbsp;&nbsp;background: linear-gradient(...);<br>
        &nbsp;&nbsp;z-index: 1;<br>
        }<br>
        .element::after {<br>
        &nbsp;&nbsp;/* Pattern overlay */<br>
        &nbsp;&nbsp;background: url(...);<br>
        &nbsp;&nbsp;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>
        &nbsp;&nbsp;/* Main triangle */<br>
        &nbsp;&nbsp;border: 10px solid transparent;<br>
        &nbsp;&nbsp;border-top-color: #e3f2fd;<br>
        }<br>
        .speech-bubble::after {<br>
        &nbsp;&nbsp;/* Secondary triangle for depth */<br>
        &nbsp;&nbsp;border: 8px solid transparent;<br>
        &nbsp;&nbsp;border-top-color: #e3f2fd;<br>
        &nbsp;&nbsp;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>
        &nbsp;&nbsp;background: linear-gradient(45deg, #ff6b6b, #4ecdc4, #45b7d1, #96ceb4);<br>
        &nbsp;&nbsp;animation: gradientMove 3s ease infinite;<br>
        &nbsp;&nbsp;background-size: 400% 400%;<br>
        }<br>
        @keyframes gradientMove {<br>
        &nbsp;&nbsp;0%, 100% { background-position: 0% 50%; }<br>
        &nbsp;&nbsp;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>
        &nbsp;&nbsp;transform: translateZ(-10px);<br>
        &nbsp;&nbsp;transition: all 0.3s ease;<br>
        }<br>
        .card-3d:hover::before {<br>
        &nbsp;&nbsp;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>
        &nbsp;&nbsp;cursor: none;<br>
        }<br>
        .custom-cursor-area::before {<br>
        &nbsp;&nbsp;/* Custom cursor */<br>
        &nbsp;&nbsp;pointer-events: none;<br>
        &nbsp;&nbsp;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>
        &nbsp;&nbsp;content: attr(data-text);<br>
        &nbsp;&nbsp;/* Offset shadow layer */<br>
        &nbsp;&nbsp;filter: blur(2px);<br>
        }<br>
        .fancy-text::after {<br>
        &nbsp;&nbsp;content: attr(data-text);<br>
        &nbsp;&nbsp;/* Second shadow layer */<br>
        &nbsp;&nbsp;filter: blur(4px);<br>
        &nbsp;&nbsp;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

::before/::after
98.5%+
content: attr()
97%+
CSS Counters
99%+
Double Colon Syntax
98%+

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!

< PreviousNext >