Labs ICT

CSS Pseudo Elements

CSS pseudo-elements allow you to style specified parts of an element, such as the first letter, first line, or before/after content. They enable sophisticated typography and decorative effects without extra HTML elements.

In this tutorial, we'll explore all major CSS pseudo-elements including ::before, ::after, ::first-letter, ::first-line, and their practical applications.

::before and ::after

The ::before and ::after pseudo-elements create virtual elements before and after the actual content of an element, perfect for decorative content and icons.

Basic ::before and ::after Syntax

/* Basic pseudo-element syntax */
.element::before {
  content: "Before text";
  color: #666;
  /* Creates content before element
  */
}

.element::after {
  content: "After text";
  color: #666;
  /* Creates content after element
  */
}

/* Required content property */
.element::before {
  /* content is required
  - Without content, pseudo-element won't appear
  */
}

/* Empty content */
.element::before {
  content: "";
  display: block;
  width: 10px;
  height: 10px;
  background-color: #007bff;
  /* Empty content for styling
  */
}

Content Values

/* String content */
.quote::before {
  content: """;
  font-size: 2em;
  color: #007bff;
}

.quote::after {
  content: """;
  font-size: 2em;
  color: #007bff;
}

/* Attribute content */
.link::after {
  content: " (" attr(href) ")";
  font-size: 0.8em;
  color: #666;
}

/* URL content */
.image::before {
  content: url("icon.png");
  display: block;
  width: 16px;
  height: 16px;
}

/* Counter content */
.list-item::before {
  content: counter(item-counter) ". ";
  font-weight: bold;
  color: #007bff;
}

/* Unicode content */
.arrow::after {
  content: "β†’";
  color: #007bff;
  margin-left: 5px;
}

/* Multiple content values */
.complex::before {
  content: "Prefix " counter(section) ": ";
  color: #666;
}

Styling Pseudo-Elements

/* Full styling */
.button::after {
  content: "β†’";
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  color: white;
  font-size: 0.8em;
  transition: transform 0.2s ease;
}

.button:hover::after {
  transform: translateY(-50%) translateX(3px);
}

/* Box model properties */
.card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 4px;
  background-color: #007bff;
}

.card::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 4px;
  background-color: #007bff;
}

/* Typography */
.heading::after {
  content: "";
  display: block;
  width: 50px;
  height: 2px;
  background-color: #007bff;
  margin: 10px auto 0;
}

::first-letter and ::first-line

The ::first-letter and ::first-line pseudo-elements allow you to style the first letter and first line of block-level elements, perfect for decorative typography.

::first-letter Pseudo-Element

/* First letter styling */
.article p::first-letter {
  font-size: 3em;
  font-weight: bold;
  color: #007bff;
  float: left;
  line-height: 1;
  margin-right: 8px;
  margin-bottom: 4px;
}

/* Drop cap effect */
.drop-cap::first-letter {
  font-size: 4em;
  font-family: Georgia, serif;
  line-height: 0.8;
  float: left;
  margin: 0.1em 0.2em 0 0;
  color: #333;
}

/* Decorative first letter */
.decorative::first-letter {
  background-color: #007bff;
  color: white;
  padding: 5px;
  border-radius: 4px;
  font-weight: bold;
  margin-right: 5px;
}

/* First letter with border */
.border-letter::first-letter {
  border: 3px solid #007bff;
  padding: 10px;
  margin-right: 10px;
  font-weight: bold;
  float: left;
}

::first-line Pseudo-Element

/* First line styling */
.article p::first-line {
  font-weight: bold;
  color: #007bff;
  text-transform: uppercase;
}

/* Newspaper-style first line */
.newspaper::first-line {
  font-size: 1.2em;
  font-weight: bold;
  color: #333;
  letter-spacing: 1px;
}

/* First line with background */
.highlight-first-line::first-line {
  background-color: #fff3cd;
  padding: 2px 4px;
  border-radius: 3px;
}

/* Limited properties */
.first-line-limitations::first-line {
  /* Limited CSS properties available:
  - font properties
  - color properties
  - background properties
  - word-spacing, letter-spacing
  - text-decoration
  - text-transform
  - line-height
  */
}

Combined First Letter and Line

/* Article styling */
.article p {
  font-size: 1.1rem;
  line-height: 1.6;
  text-align: justify;
}

.article p::first-letter {
  font-size: 2.5em;
  font-weight: bold;
  color: #007bff;
  float: left;
  margin: 0.1em 0.2em 0 0;
  line-height: 1;
}

.article p::first-line {
  font-weight: bold;
  color: #333;
  text-transform: uppercase;
}

/* Magazine-style heading */
.magazine-heading::first-letter {
  font-size: 3em;
  font-family: Georgia, serif;
  color: #007bff;
  float: left;
  margin: 0 0.2em 0.1em 0;
  line-height: 0.8;
}

.magazine-heading::first-line {
  font-size: 1.3em;
  font-weight: normal;
  color: #333;
  text-transform: none;
}

::selection and ::placeholder

The ::selection and ::placeholder pseudo-elements style text selection and form placeholder text respectively.

::selection Pseudo-Element

/* Text selection styling */
::selection {
  background-color: #007bff;
  color: white;
}

/* Custom selection colors */
.custom-selection::selection {
  background-color: #28a745;
  color: white;
  text-shadow: none;
}

/* Limited selection properties */
.selection-limited::selection {
  /* Limited properties available:
  - color
  - background-color
  - text-decoration
  - text-shadow
  - stroke-color, stroke-width (Firefox)
  */
}

/* Firefox-specific selection */
.custom-selection::-moz-selection {
  background-color: #28a745;
  color: white;
}

/* Selection with gradients */
.gradient-selection::selection {
  background: linear-gradient(45deg, #007bff, #0056b3);
  color: white;
}

::placeholder Pseudo-Element

/* Placeholder styling */
input::placeholder {
  color: #6c757d;
  font-style: italic;
  opacity: 0.7;
}

textarea::placeholder {
  color: #6c757d;
  font-style: italic;
  opacity: 0.7;
}

/* Placeholder with specific styling */
.custom-placeholder::placeholder {
  color: #007bff;
  font-weight: 500;
  opacity: 0.8;
}

/* Placeholder positioning */
.positioned-placeholder::placeholder {
  padding: 10px;
  text-align: center;
  background-color: #f8f9fa;
  border-radius: 4px;
}

/* Placeholder with icons */
.icon-placeholder::placeholder {
  color: transparent;
  background-image: url("search-icon.png");
  background-repeat: no-repeat;
  background-position: 10px center;
  padding-left: 40px;
}

Browser Compatibility

/* Cross-browser placeholder */
.placeholder-compatible::placeholder {
  color: #6c757d;
  font-style: italic;
}

/* WebKit browsers */
.placeholder-compatible::-webkit-input-placeholder {
  color: #6c757d;
  font-style: italic;
}

/* Mozilla browsers */
.placeholder-compatible::-moz-placeholder {
  color: #6c757d;
  font-style: italic;
}

/* Internet Explorer */
.placeholder-compatible:-ms-input-placeholder {
  color: #6c757d;
  font-style: italic;
}

::marker and ::backdrop

The ::marker and ::backdrop pseudo-elements style list markers and modal backdrops respectively.

::marker Pseudo-Element

/* List marker styling */
ul::marker {
  color: #007bff;
  font-size: 1.2em;
}

ol::marker {
  color: #28a745;
  font-weight: bold;
}

/* Custom markers */
.custom-list::marker {
  content: "β†’";
  color: #007bff;
  font-size: 1.5em;
}

/* Marker with background */
.marker-background::marker {
  background-color: #007bff;
  color: white;
  padding: 2px 6px;
  border-radius: 12px;
  font-weight: bold;
}

/* Marker positioning */
.positioned-marker::marker {
  font-size: 0.8em;
  vertical-align: middle;
}

/* Limited marker properties */
.marker-limitations::marker {
  /* Limited properties available:
  - color
  - font properties
  - text properties
  - content (with ::before/::after)
  */
}

::backdrop Pseudo-Element

/* Modal backdrop styling */
.modal::backdrop {
  background-color: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(5px);
}

/* Dialog backdrop */
dialog::backdrop {
  background-color: rgba(0, 0, 0, 0.8);
  backdrop-filter: blur(3px) grayscale(0.5);
}

/* Backdrop with animation */
.animated-backdrop::backdrop {
  background-color: rgba(0, 0, 0, 0);
  animation: fadeIn 0.3s ease forwards;
}

@keyframes fadeIn {
  to {
    background-color: rgba(0, 0, 0, 0.5);
  }
}

/* Backdrop with gradient */
.gradient-backdrop::backdrop {
  background: linear-gradient(45deg, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.7));
}

Backdrop Applications

/* Lightbox backdrop */
.lightbox::backdrop {
  background-color: rgba(0, 0, 0, 0.8);
  backdrop-filter: blur(8px);
}

.lightbox::backdrop:active {
  background-color: rgba(0, 0, 0, 0.9);
}

/* Menu backdrop */
.menu-backdrop::backdrop {
  background-color: transparent;
}

.menu-backdrop:active::backdrop {
  background-color: rgba(0, 0, 0, 0.3);
}

/* Loading backdrop */
.loading-backdrop::backdrop {
  background-color: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(2px);
}

.loading-backdrop::backdrop::before {
  content: "Loading...";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #333;
  font-size: 1.2rem;
}

Advanced Pseudo-Elements

Advanced pseudo-elements provide more sophisticated styling capabilities for specific element parts and states.

::part Pseudo-Element

/* Styling web component parts */
custom-element::part(header) {
  background-color: #007bff;
  color: white;
  padding: 1rem;
}

custom-element::part(content) {
  padding: 1rem;
  line-height: 1.6;
}

custom-element::part(footer) {
  background-color: #f8f9fa;
  padding: 1rem;
  border-top: 1px solid #dee2e6;
}

/* Multiple parts */
custom-element::part(header, footer) {
  background-color: #007bff;
  color: white;
}

/* Nested parts */
custom-element::part(header)::part(title) {
  font-size: 1.5rem;
  font-weight: bold;
}

::slotted Pseudo-Element

/* Styling slotted content */
custom-element::slotted(*) {
  color: #333;
  line-height: 1.6;
}

custom-element::slotted(p) {
  margin-bottom: 1rem;
}

custom-element::slotted(.highlight) {
  background-color: #fff3cd;
  padding: 0.5rem;
  border-radius: 4px;
}

/* Slotted with specificity */
custom-element::slotted(.important) {
  font-weight: bold;
  color: #007bff;
}

::file-selector-button

/* File input button styling */
input[type="file"]::file-selector-button {
  background-color: #007bff;
  color: white;
  border: none;
  padding: 0.5rem 1rem;
  border-radius: 4px;
  cursor: pointer;
}

input[type="file"]::file-selector-button:hover {
  background-color: #0056b3;
}

/* File selector text */
input[type="file"]::file-selector-text {
  color: #333;
  font-size: 0.9rem;
}

input[type="file"]::file-selector-button:hover::file-selector-text {
  color: white;
}

::grammar-error and ::spelling-error

/* Grammar error styling */
::grammar-error {
  text-decoration: wavy underline;
  text-decoration-color: #ffc107;
  text-decoration-style: wavy;
}

/* Spelling error styling */
::spelling-error {
  text-decoration: wavy underline;
  text-decoration-color: #dc3545;
  text-decoration-style: wavy;
}

/* Combined error styling */
.error-text::grammar-error,
.error-text::spelling-error {
  background-color: #f8d7da;
  padding: 2px 4px;
  border-radius: 3px;
}

Pseudo-Element Combinations

Combining pseudo-elements enables powerful styling patterns and complex visual effects.

Multiple Pseudo-Elements

/* Multiple pseudo-elements on one element */
.quote::before,
.quote::after {
  font-size: 2em;
  color: #007bff;
}

.quote::before {
  content: """;
  margin-right: 5px;
}

.quote::after {
  content: """;
  margin-left: 5px;
}

/* Complex combinations */
.card::before,
.card::after {
  content: "";
  position: absolute;
  width: 0;
  height: 0;
  border-style: solid;
}

.card::before {
  top: 0;
  left: 0;
  border-width: 20px 20px 0 20px;
  border-color: transparent transparent #007bff transparent transparent;
}

.card::after {
  bottom: 0;
  right: 0;
  border-width: 20px 20px 20px 0;
  border-color: transparent transparent #007bff transparent transparent;
}

/* First letter with before/after */
.drop-cap::first-letter {
  font-size: 3em;
  float: left;
  margin: 0.1em 0.2em 0 0;
  line-height: 1;
}

.drop-cap::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 2px;
  background-color: #007bff;
}

Pseudo-Elements with Pseudo-Classes

/* Hover effects with pseudo-elements */
.button:hover::after {
  content: "β†’";
  transform: translateX(5px);
  transition: transform 0.2s ease;
}

.button:hover::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255, 255, 255, 0.1);
}

/* Focus effects */
.input:focus::placeholder {
  opacity: 0;
  transition: opacity 0.2s ease;
}

.input:not(:focus)::placeholder {
  opacity: 1;
}

/* Active states */
.button:active::after {
  transform: translateX(2px);
}

.button:active::before {
  background-color: rgba(0, 0, 0, 0.2);
}

/* Disabled states */
.button:disabled::after {
  content: "";
  display: none;
}

.button:disabled::before {
  opacity: 0.5;
}

Nested Pseudo-Elements

/* Nested pseudo-elements */
.list-item::before {
  content: counter(item-counter) ". ";
  font-weight: bold;
  color: #007bff;
}

.list-item::before::before {
  content: "Item ";
  font-size: 0.8em;
  color: #666;
}

/* Complex nested structure */
.complex-element::before {
  content: "Prefix";
  color: #007bff;
  font-weight: bold;
}

.complex-element::before::after {
  content: " - ";
  color: #666;
  font-size: 0.8em;
}

.complex-element::after {
  content: "Suffix";
  color: #28a745;
  font-style: italic;
}

Practical Applications

Pseudo-elements are commonly used for specific UI patterns and decorative effects.

Icon Buttons

/* Button with icon using pseudo-element */
.icon-button {
  position: relative;
  padding-left: 30px;
  background-color: #007bff;
  color: white;
  border: none;
  padding: 10px 20px 10px 20px;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.icon-button::before {
  content: "☰";
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 16px;
}

.icon-button:hover {
  background-color: #0056b3;
}

.icon-button:hover::before {
  transform: translateY(-50%) scale(1.1);
}

/* Download button */
.download-button::after {
  content: "↓";
  margin-left: 8px;
  font-size: 0.8em;
}

.download-button:hover::after {
  transform: translateY(-2px);
}

/* External link button */
.external-link::after {
  content: "β†—";
  margin-left: 5px;
  font-size: 0.8em;
}

Decorative Quotes

/* Styled blockquote */
.blockquote {
  position: relative;
  padding: 20px;
  margin: 20px 0;
  background-color: #f8f9fa;
  border-left: 4px solid #007bff;
  font-style: italic;
}

.blockquote::before {
  content: """;
  position: absolute;
  top: -20px;
  left: -20px;
  font-size: 60px;
  color: #007bff;
  font-family: Georgia, serif;
}

.blockquote::after {
  content: """;
  position: absolute;
  bottom: -40px;
  right: -20px;
  font-size: 60px;
  color: #007bff;
  font-family: Georgia, serif;
}

/* Citation */
.cite::before {
  content: "β€” ";
  color: #666;
  font-style: italic;
}

Loading States

/* Loading button */
.loading-button {
  position: relative;
  padding-right: 40px;
}

.loading-button::after {
  content: "";
  position: absolute;
  right: 15px;
  top: 50%;
  width: 16px;
  height: 16px;
  margin: -8px 0 0 0;
  border: 2px solid #007bff;
  border-radius: 50%;
  border-top-color: transparent;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* Loading card */
.loading-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255, 255, 255, 0.9);
  z-index: 10;
}

.loading-card::before::after {
  content: "Loading...";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #333;
  font-weight: bold;
}

Badge and Notifications

/* Badge using pseudo-element */
.badge-container {
  position: relative;
}

.badge-container::after {
  content: attr(data-badge);
  position: absolute;
  top: -8px;
  right: -8px;
  background-color: #dc3545;
  color: white;
  font-size: 0.75rem;
  font-weight: bold;
  padding: 2px 6px;
  border-radius: 10px;
  min-width: 20px;
  text-align: center;
}

/* Notification dot */
.notification::after {
  content: "";
  position: absolute;
  top: 5px;
  right: 5px;
  width: 8px;
  height: 8px;
  background-color: #dc3545;
  border-radius: 50%;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

/* Status indicator */
.status-indicator::before {
  content: "";
  position: absolute;
  top: 50%;
  left: -10px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  transform: translateY(-50%);
}

.status-indicator.online::before {
  background-color: #28a745;
}

.status-indicator.offline::before {
  background-color: #6c757d;
}

Typography Effects

Pseudo-elements are perfect for creating sophisticated typography effects and decorative text styling.

Advanced Drop Caps

/* Advanced drop cap */
.article p {
  font-size: 1.1rem;
  line-height: 1.6;
}

.article p::first-letter {
  font-size: 4em;
  font-family: Georgia, serif;
  line-height: 0.8;
  float: left;
  margin: 0.15em 0.2em 0.1em 0;
  padding: 0.2em;
  border: 3px solid #007bff;
  border-radius: 8px;
  background: linear-gradient(135deg, #f8f9fa, #e9ecef);
  box-shadow: 0 4px 8px rgba(0, 123, 255, 0.2);
}

/* Decorated drop cap */
.decorated-drop-cap::first-letter {
  font-size: 3.5em;
  font-weight: bold;
  color: #007bff;
  float: left;
  margin: 0.1em 0.2em 0 0;
  line-height: 1;
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
}

.decorated-drop-cap::first-line {
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
}

Text Decorations

/* Underline decoration */
.underlined-text {
  position: relative;
  text-decoration: none;
}

.underlined-text::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 2px;
  background-color: #007bff;
}

/* Animated underline */
.animated-underline::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 0;
  height: 2px;
  background-color: #007bff;
  transition: width 0.3s ease;
}

.animated-underline:hover::after {
  width: 100%;
}

/* Strikethrough effect */
.strikethrough-text::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: 2px;
  background-color: #dc3545;
}

/* Highlight effect */
.highlighted-text::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255, 235, 59, 0.2);
  z-index: -1;
}

List Styling

/* Custom list markers */
.custom-list {
  list-style: none;
  padding-left: 0;
}

.custom-list li {
  position: relative;
  padding-left: 30px;
  margin-bottom: 10px;
}

.custom-list li::before {
  content: "β†’";
  position: absolute;
  left: 0;
  top: 0;
  color: #007bff;
  font-weight: bold;
}

/* Numbered list with custom style */
.custom-numbered-list {
  list-style: none;
  counter-reset: custom-counter;
  padding-left: 0;
}

.custom-numbered-list li {
  position: relative;
  padding-left: 40px;
  margin-bottom: 10px;
}

.custom-numbered-list li::before {
  content: counter(custom-counter);
  position: absolute;
  left: 0;
  top: 0;
  width: 25px;
  height: 25px;
  background-color: #007bff;
  color: white;
  text-align: center;
  line-height: 25px;
  border-radius: 50%;
  font-weight: bold;
  counter-increment: custom-counter;
}

/* Nested list styling */
.nested-list li::before {
  content: counter(item-counter, lower-roman) ". ";
  color: #007bff;
  font-weight: bold;
}

.nested-list li {
  counter-increment: item-counter;
}

Pseudo-Element Best Practices

βœ“ Do:

  • Use pseudo-elements for decorative content
  • Consider accessibility when using pseudo-elements
  • Test pseudo-elements across different browsers
  • Use appropriate content for the context
  • Consider performance with complex pseudo-elements
  • Use pseudo-elements to reduce HTML markup
  • Document pseudo-element logic for maintainability

βœ— Don't:

  • Use pseudo-elements for important content
  • Forget about content property requirements
  • Overuse pseudo-elements unnecessarily
  • Ignore browser compatibility issues
  • Use pseudo-elements that break accessibility
  • Create pseudo-elements without semantic meaning
  • Forget about performance implications

Accessibility Considerations

β™Ώ Accessibility Tips:

  • Screen readers: Test pseudo-element content with screen readers
  • Content meaning: Ensure pseudo-element content adds meaning
  • Color contrast: Maintain sufficient contrast for pseudo-element content
  • Focus indicators: Don't rely solely on pseudo-elements for focus states
  • Reduced motion: Respect user motion preferences

Performance Considerations

⚑ Performance Tips:

  • Limit pseudo-elements: Avoid too many on one page
  • Avoid complex animations: Simple animations perform better
  • Use transform for animations: Better than position/left/top
  • Avoid expensive filters: Especially on pseudo-elements
  • Test with large DOM: Performance degrades with complexity

Browser Compatibility

🌐 Compatibility Notes:

  • ::before/::after: Universal support (IE8+ with single colon)
  • ::first-letter/::first-line: Universal support
  • ::selection: Modern browsers (IE9+)
  • ::placeholder: Modern browsers (IE10+)
  • ::marker: Modern browsers (Firefox 68+, Chrome 86+)
  • ::backdrop: Modern browsers (Chrome 76+, Firefox 103+)
  • Use vendor prefixes for older browsers

Complete Example

Comprehensive Pseudo-Element System

/* Pseudo-element system variables */
:root {
  /* Colors */
  --pseudo-primary: #007bff;
  --pseudo-success: #28a745;
  --pseudo-warning: #ffc107;
  --pseudo-danger: #dc3545;
  --pseudo-info: #17a2b8;
  
  /* Spacing */
  --pseudo-gap-sm: 0.5rem;
  --pseudo-gap-md: 1rem;
  --pseudo-gap-lg: 1.5rem;
  
  /* Typography */
  --pseudo-font-serif: Georgia, serif;
  --pseudo-font-mono: 'Courier New', monospace;
}

/* Basic pseudo-elements */
.before-content::before {
  content: "Before: ";
  color: var(--pseudo-primary);
  font-weight: bold;
}

.after-content::after {
  content: " :After";
  color: var(--pseudo-primary);
  font-style: italic;
}

/* Typography pseudo-elements */
.drop-cap::first-letter {
  font-size: 3em;
  font-family: var(--pseudo-font-serif);
  line-height: 0.8;
  float: left;
  margin: 0.1em var(--pseudo-gap-md) 0 0;
  color: var(--pseudo-primary);
}

.first-line-highlight::first-line {
  font-weight: bold;
  color: var(--pseudo-primary);
  background-color: rgba(0, 123, 255, 0.1);
  padding: 2px 4px;
  border-radius: 3px;
}

/* Selection styling */
.custom-selection::selection {
  background-color: var(--pseudo-primary);
  color: white;
  text-shadow: none;
}

.custom-selection::-moz-selection {
  background-color: var(--pseudo-primary);
  color: white;
}

/* Placeholder styling */
.custom-placeholder::placeholder {
  color: #6c757d;
  font-style: italic;
  opacity: 0.7;
}

/* List styling */
.custom-list {
  list-style: none;
  padding-left: 0;
  counter-reset: custom-list-counter;
}

.custom-list li {
  position: relative;
  padding-left: 30px;
  margin-bottom: var(--pseudo-gap-sm);
}

.custom-list li::before {
  content: counter(custom-list-counter);
  position: absolute;
  left: 0;
  top: 0;
  width: 20px;
  height: 20px;
  background-color: var(--pseudo-primary);
  color: white;
  text-align: center;
  line-height: 20px;
  border-radius: 50%;
  font-weight: bold;
  counter-increment: custom-list-counter;
}

/* Button pseudo-elements */
.icon-button {
  position: relative;
  padding-left: 35px;
  background-color: var(--pseudo-primary);
  color: white;
  border: none;
  padding: var(--pseudo-gap-md) var(--pseudo-gap-lg) var(--pseudo-gap-md) 35px;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.icon-button::before {
  content: "☰";
  position: absolute;
  left: var(--pseudo-gap-md);
  top: 50%;
  transform: translateY(-50%);
  font-size: 16px;
}

.icon-button:hover {
  background-color: #0056b3;
}

.icon-button:hover::before {
  transform: translateY(-50%) scale(1.1);
}

.icon-button:active {
  transform: scale(0.98);
}

/* Badge pseudo-elements */
.badge-item {
  position: relative;
  margin-right: var(--pseudo-gap-md);
}

.badge-item::after {
  content: attr(data-badge);
  position: absolute;
  top: -8px;
  right: -8px;
  background-color: var(--pseudo-danger);
  color: white;
  font-size: 0.75rem;
  font-weight: bold;
  padding: 2px 6px;
  border-radius: 10px;
  min-width: 20px;
  text-align: center;
  animation: badgeAppear 0.3s ease;
}

@keyframes badgeAppear {
  from {
    opacity: 0;
    transform: scale(0.5);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* Quote pseudo-elements */
.styled-quote {
  position: relative;
  padding: var(--pseudo-gap-lg);
  margin: var(--pseudo-gap-lg) 0;
  background-color: #f8f9fa;
  border-left: 4px solid var(--pseudo-primary);
  font-style: italic;
}

.styled-quote::before {
  content: """;
  position: absolute;
  top: -20px;
  left: -20px;
  font-size: 3em;
  color: var(--pseudo-primary);
  font-family: var(--pseudo-font-serif);
}

.styled-quote::after {
  content: """;
  position: absolute;
  bottom: -40px;
  right: -20px;
  font-size: 3em;
  color: var(--pseudo-primary);
  font-family: var(--pseudo-font-serif);
}

.styled-quote p {
  margin: 0;
}

/* Card pseudo-elements */
.elevated-card {
  position: relative;
  padding: var(--pseudo-gap-lg);
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
}

.elevated-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 4px;
  background-color: var(--pseudo-primary);
  border-radius: 8px 8px 0 0;
}

.elevated-card::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 4px;
  background-color: var(--pseudo-primary);
  border-radius: 0 0 8px 8px;
}

.elevated-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}

/* Loading pseudo-elements */
.loading-element {
  position: relative;
  pointer-events: none;
}

.loading-element::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255, 255, 255, 0.8);
  z-index: 10;
}

.loading-element::after {
  content: "Loading...";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: var(--pseudo-primary);
  font-weight: bold;
  font-size: 1.1rem;
}

.loading-element::before {
  animation: pulse 1.5s infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 0.8; }
  50% { opacity: 0.4; }
}

/* Navigation pseudo-elements */
.nav-item {
  position: relative;
}

.nav-item::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 0;
  height: 2px;
  background-color: var(--pseudo-primary);
  transform: translateX(-50%);
  transition: width 0.3s ease;
}

.nav-item:hover::after {
  width: 80%;
}

.nav-item.active::after {
  width: 100%;
  background-color: var(--pseudo-success);
}

/* Form pseudo-elements */
.form-field {
  position: relative;
  margin-bottom: var(--pseudo-gap-lg);
}

.form-field::before {
  content: attr(data-label);
  position: absolute;
  top: -10px;
  left: 0;
  font-size: 0.8rem;
  color: var(--pseudo-primary);
  font-weight: bold;
}

.form-field:focus::before {
  color: var(--pseudo-success);
}

.form-field:invalid::before {
  color: var(--pseudo-danger);
}

.form-field::after {
  content: attr(data-hint);
  position: absolute;
  bottom: -20px;
  left: 0;
  font-size: 0.75rem;
  color: #6c757d;
  font-style: italic;
}

/* Responsive pseudo-elements */
@media (max-width: 768px) {
  .drop-cap::first-letter {
    font-size: 2.5em;
  }
  
  .icon-button {
    padding-left: 30px;
  }
  
  .icon-button::before {
    left: var(--pseudo-gap-sm);
    font-size: 14px;
  }
  
  .styled-quote {
    padding: var(--pseudo-gap-md);
  }
}

/* Accessibility improvements */
@media (prefers-reduced-motion: reduce) {
  .loading-element::before {
    animation: none;
  }
  
  .badge-item::after {
    animation: none;
  }
  
  .elevated-card {
    transition: none;
  }
}

@media (prefers-contrast: high) {
  .icon-button,
  .elevated-card {
    border: 2px solid #000;
  }
}

/* Print styles */
@media print {
  .icon-button::before,
  .badge-item::after,
  .loading-element::before,
  .loading-element::after {
    display: none;
  }
}

Summary

CSS pseudo-elements are powerful tools for creating decorative content, styling specific parts of elements, and enhancing typography without additional HTML markup.

Key Takeaways:

  • ::before and ::after create decorative content
  • ::first-letter and ::first-line style text parts
  • ::selection and ::placeholder style specific states
  • ::marker styles list bullets and numbers
  • ::backdrop styles modal and dialog backgrounds
  • Consider accessibility when using pseudo-elements
  • Test pseudo-elements across different browsers

Remember: Pseudo-elements are about enhancing contentβ€”understanding when and how to use them creates more sophisticated and maintainable stylesheets!

πŸ§ͺ Quick Quiz

What does ::before do?