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!