Understanding the CSS Content Property
The CSS content property is a powerful tool that defines what is rendered inside an element or pseudo-element. Unlike most CSS properties that modify existing content, the content property actually replaces or generates new content entirely.
For regular elements, the content property specifies whether to render normally or replace content with an image. For pseudo-elements like ::before and ::after, it defines what text, images, or combinations to display. Objects inserted using the content property are considered anonymous replaced elements--they exist in the render tree but have no corresponding HTML element.
According to MDN Web Docs, this property is primarily used with pseudo-elements to inject content without modifying your HTML markup.
Syntax and Basic Usage
The content property accepts several types of values that can be combined:
- Keywords:
normal(default behavior) andnone(no content generated) - String values: Text content in quotes
- Image values: Using
url(),image-set(), or gradient functions - Counter values: With
counter()andcounters()functions - Quote values: For handling quotation marks
- Alternative text: Using the slash syntax for accessibility (e.g.,
url("icon.png") / "Description")
1/* Keywords */2content: normal;3content: none;4 5/* String values */6content: "Hello";7content: "→ " "Section " counter(section);8 9/* Image values */10content: url("icon.svg");11content: linear-gradient(#e66465, #9198e5);12 13/* Counter values */14content: counter(chapter);15content: counters(section, ".");16 17/* Quote values */18content: open-quote;19content: close-quote;20 21/* Alternative text for accessibility */22content: url("star.svg") / "Rating: ";23 24/* Combined values */25content: "Note: " url("note.svg") " Important";Content Property Values Deep Dive
Understanding each value type helps you leverage the full power of the content property. Each category serves specific use cases in web development.
String values are the most common use of the content property. You can insert any text by wrapping it in quotes:
/* Simple text */
.note::before {
content: "Note: ";
}
/* Concatenate multiple strings */
.chapter::before {
content: "Chapter " counter(chapter) ": ";
}
/* Unicode characters */
.external-link::after {
content: " \2197"; /* ↗ arrow */
}
/* Escaping quotes */
.quote::before {
content: "\"";
}
Strings can contain regular text, Unicode escape sequences, or be concatenated with other content types.
Generated Content with Pseudo-Elements
The content property is most commonly used with ::before and ::after pseudo-elements. These create virtual elements that appear before or after an element's actual content without modifying HTML.
Key points about pseudo-elements:
::beforecreates content before the element's children::aftercreates content after the element's children- Pseudo-elements require the content property to render (even
content: ""for purely decorative uses) - They're inline by default--use
displayto change this - They inherit styles from their parent element
Per MDN Web Docs, pseudo-elements are ideal for icons, decorative elements, labels, and UI enhancements.
Practical Use Cases
Here are common patterns for generated content:
- Adding icons before links -- Indicate external links, downloads, or file types
- Creating visual separators -- Breadcrumb dividers, list separators
- Displaying attribute values -- Show href, title, or data attributes with
attr() - Building custom list markers -- Replace default bullets with custom designs
- Generating document footnotes -- Auto-numbered references
These techniques enhance user experience while keeping HTML semantic and clean. For more CSS layout techniques, see our guides on Flexbox and Padding. To implement these optimizations in a production environment, our web development services can help you achieve optimal performance across your entire site.
1/* Icon before external links */2a[href^="http"]::after {3 content: " \2197"; /* ↗ external link icon */4 font-size: 0.8em;5}6 7/* Breadcrumb separator */8.breadcrumb li:not(:last-child)::after {9 content: " / ";10 color: #6b7280;11 margin: 0 0.5rem;12}13 14/* Display href attribute on print */15@media print {16 a[href^="http"]::after {17 content: " (" attr(href) ")";18 font-size: 0.8em;19 color: #666;20 }21}22 23/* Custom checkbox styling */24.checkbox:checked::before {25 content: "✓";26 color: #10b981;27 font-weight: bold;28}29 30/* Required field indicator */31.required::after {32 content: " *";33 color: #ef4444;34}35 36/* Tooltip-style data display */37[data-tooltip]::after {38 content: attr(data-tooltip);39 position: absolute;40 background: #1f2937;41 color: white;42 padding: 0.5rem;43 border-radius: 4px;44 opacity: 0;45 transition: opacity 0.2s;46}47[data-tooltip]:hover::after {48 opacity: 1;49}Content-Visibility for Performance Optimization
While the content property controls what is rendered, the content-visibility property controls whether content is rendered at all. This distinction makes content-visibility a powerful performance optimization tool.
As documented by web.dev, content-visibility enables browsers to skip rendering work for off-screen content. For long pages with substantial below-the-fold content, this can dramatically reduce initial load times and improve Core Web Vitals.
The property is part of the CSS Containment specification, which provides ways to isolate DOM subtrees from the rest of the page for optimization purposes. Combined with our SEO services, implementing these performance optimizations can significantly boost your search rankings by improving page speed metrics that search engines prioritize.
How Content-Visibility Works
According to DebugBear's analysis, when you apply content-visibility: auto to an element:
- Layout is skipped -- The browser doesn't calculate positions for off-screen children
- Style calculation is skipped -- No computed styles for hidden descendants
- Paint is skipped -- No pixel rendering for invisible content
- Rendering is just-in-time -- Content renders as users scroll it into view
- DOM remains accessible -- Elements stay in the accessibility tree and are searchable
This lazy-rendering approach means the browser only does work when absolutely necessary, similar to how modern image lazy-loading works.
Understanding the three main values for the content-visibility property
visible
Default behavior where content is processed, laid out, and displayed normally. No performance optimization is applied, ensuring all content is immediately available.
hidden
Content is not displayed, but the element's rendering state is fully preserved. Unlike display: none, switching to visible is instantaneous since the browser maintains cached render data.
auto
The browser automatically skips rendering for off-screen content and renders it just-in-time when scrolled into view. This provides the biggest performance boost for long pages.
1/* Apply to sections below the fold */2.article-section {3 content-visibility: auto;4 contain-intrinsic-size: auto 500px;5}6 7/* Blog post cards in a feed */8.post-card {9 content-visibility: auto;10 contain-intrinsic-size: auto 300px;11}12 13/* Heavy component with complex styles */14.data-visualization {15 content-visibility: auto;16 contain-intrinsic-size: 100% 400px;17}18 19/* Footer - typically below fold */20footer {21 content-visibility: auto;22 contain-intrinsic-size: auto 200px;23}When to Use Content-Visibility
Content-visibility delivers the best results in specific scenarios:
- Below-the-fold content sections -- Anything users won't see immediately
- Long article pages -- Posts with many sections or chapters
- Feed-style layouts -- Social feeds, product grids, blog listings
- Heavy components -- Data visualizations, complex forms, rich media sections
- Footers and sidebars -- Secondary content that's often off-screen
The more complex the hidden content, the greater the performance gains.
When NOT to Use Content-Visibility
DebugBear warns against applying content-visibility in these scenarios:
- Above-the-fold content -- Visible content must render immediately
- Largest Contentful Paint (LCP) elements -- Delays hurt Core Web Vitals
- Simple, lightweight elements -- Overhead may exceed savings
- Elements affecting critical layout -- May cause layout shifts
- Sticky or fixed elements -- Need continuous rendering
For styling considerations related to page layout, our guides on Visibility and Border cover complementary techniques. If you're building complex web applications that require these optimizations at scale, our AI automation services can help streamline your development workflow.
| Scenario | Use content-visibility? | Reason |
|---|---|---|
| Below-fold sections | Yes | Not immediately visible; skip rendering until scrolled |
| Long article pages | Yes | Multiple sections benefit from deferred rendering |
| Above-fold content | No | Must render immediately for user experience |
| LCP elements | No | Delays negatively impact Core Web Vitals scores |
| Simple elements | Avoid | Containment overhead may exceed rendering savings |
CSS Containment Fundamentals
The contain property is the foundation underlying content-visibility. CSS containment isolates DOM subtrees from the rest of the page, enabling significant browser rendering optimizations.
When you use content-visibility: auto, the browser automatically applies layout, style, and paint containment. Understanding these containment types helps you use them independently for fine-grained control. This is particularly valuable for large-scale applications and content-heavy websites where every millisecond of rendering time impacts user experience and search rankings.
For implementing these advanced CSS techniques across your entire website, our web development team specializes in performance optimization strategies that combine CSS containment with modern rendering patterns.
1/* Individual containment types */2.widget {3 contain: layout;4}5 6.counter-section {7 contain: style;8}9 10.card {11 contain: paint;12}13 14/* Combined containment */15.isolated-component {16 contain: layout style paint;17}18 19/* Shorthand: strict = size layout style paint */20.fully-contained {21 contain: strict;22}23 24/* Shorthand: content = layout style paint (no size) */25.content-contained {26 contain: content;27}Browser Support
The CSS content property enjoys full browser support across all modern browsers including Chrome, Firefox, Safari, and Edge. You can use it confidently without fallbacks.
The content-visibility property has strong support:
- Chrome/Edge: Full support since version 85
- Firefox: Supported since version 125
- Safari: Supported since version 18
For older browsers, content-visibility gracefully degrades--content simply renders normally without the performance optimization. This makes it safe to implement as a progressive enhancement:
/* Works in all browsers, optimizes in supporting ones */
.article-section {
content-visibility: auto;
contain-intrinsic-size: auto 500px;
}
No feature detection is required since unsupported browsers ignore unknown properties.
Practical Implementation Examples
The following examples demonstrate real-world applications of content and content-visibility properties that you can adapt for your projects.
1/* Only optimize posts after the first two (below fold) */2.blog-post:nth-child(n+3) {3 content-visibility: auto;4 contain-intrinsic-size: auto 600px;5}6 7/* Optimize all article sections except the intro */8.article-section:not(:first-child) {9 content-visibility: auto;10 contain-intrinsic-size: auto 400px;11}12 13/* Footer optimization */14.site-footer {15 content-visibility: auto;16 contain-intrinsic-size: auto 250px;17}18 19/* Comments section - typically far below fold */20.comments-section {21 content-visibility: auto;22 contain-intrinsic-size: auto 800px;23}24 25/* Related posts sidebar */26.related-posts {27 content-visibility: auto;28 contain-intrinsic-size: auto 350px;29}1/* Navigation icon system */2.nav-link {3 display: flex;4 align-items: center;5 gap: 0.5rem;6}7 8.nav-link::before {9 font-family: 'Icon Font', sans-serif;10 font-size: 1.2em;11}12 13/* Specific icons by link type */14.nav-link[href="/"]::before {15 content: "\e900"; /* home icon */16}17 18.nav-link[href*="/services/"]::before {19 content: "\e901"; /* services icon */20}21 22.nav-link[href*="/contact/"]::before {23 content: "\e902"; /* contact icon */24}25 26/* External link indicator */27.nav-link[href^="http"]::after {28 content: " \2197";29 font-size: 0.8em;30 opacity: 0.7;31}32 33/* Download file type indicator */34a[href$=".pdf"]::after {35 content: " (PDF)";36 font-size: 0.85em;37 color: #6b7280;38}Frequently Asked Questions
Best Practices Summary
Mastering the CSS content property and content-visibility optimization requires balancing functionality with performance:
- Use content for decoration -- Reserve generated content for supplementary, decorative elements like icons, separators, and visual indicators
- Apply content-visibility: auto strategically -- Target heavy, off-screen content sections for maximum rendering performance gains
- Always pair with contain-intrinsic-size -- Prevent scrollbar jumping by providing placeholder dimensions for deferred content
- Test accessibility -- Verify pseudo-element content with screen readers; keep critical information in actual DOM
- Measure performance impact -- Use browser DevTools to confirm improvements before deploying
- Avoid premature optimization -- Don't add complexity for simple elements where overhead exceeds benefits
Related CSS Properties
Explore related properties and techniques covered in this cluster:
- Visibility -- Control element visibility without affecting layout
- Flexbox -- Modern layout system for responsive designs
- Padding -- Space inside element borders
- Border -- Element border styling
For comprehensive performance optimization across your entire website, our web development services can help you implement these techniques along with broader performance strategies.