The content property inserts generated content — usually on ::before and ::after. You can add a string, pull an attribute with attr(), show a counter, or use quote keywords.
The initial value is normal (on ::before / ::after that means nothing is generated). It is not inherited. Use it for decoration and labels you could live without if CSS failed — keep essential meaning in HTML.
Baseline for common values.
Not deprecated. Strings, none, attr(), counters, and quotes are widely available. Alternative text after / (e.g. content: "★" / "star") has limited support — prefer HTML for critical labels.
Generated content is powerful — and easy to misuse.
a11y
Not for critical information
Generated text may be ignored by assistive tech. Put required meaning in HTML, not only in content.
target
Needs a pseudo-element for strings
Beginners should set content on ::before or ::after. A string on a plain div will not replace its child text as you might expect.
quotes
Missing quotes look empty
open-quote / close-quote need a sensible quotes value (or browser defaults) or the marks may be wrong or invisible.
alt
Slash alt text is limited
content: url(icon.png) / "Label" is useful when supported, but support is incomplete. Prefer real HTML for important labels.
space
Spaces must be inside the string
Write content: " New!" with a leading space if you need a gap. CSS does not add one automatically.
Compatibility
Browser Support
content is a browser CSS property for generated content. Node.js, Deno, and Bun do not apply it.
✓ Baseline · Widely available
content
Strings, none, normal, attr(), counters, and quotes are widely supported. Alternative text after / and some newer functions have limited support.
100%Common values
Google ChromeAll versions
Full support
Mozilla FirefoxAll versions
Full support
Apple SafariAll versions
Full support
Microsoft EdgeAll versions
Full support
OperaAll versions
Full support
Samsung InternetAll versions
Full support
Internet Explorer8+
Full support
contentWidely supported
Bottom line: Safe for everyday ::before / ::after strings, attr(), and counters. Treat slash alt text as progressive. It is not a runtime API.
Remember
Key Takeaways
Role: define generated content for pseudo-elements like ::before and ::after.
Initial value:normal (acts like none on those pseudo-elements).
Common tools: strings, attr(), counter(), and quote keywords.
Accessibility: decoration only — keep real meaning in HTML.
One line:content fills ::before / ::after with generated text — use it for polish, not for essential copy.
Frequently Asked Questions
It defines generated content for ::before and ::after (and some other pseudo-elements). Strings, attr(), counters, quotes, and images are common values.
The initial value is normal. On ::before and ::after, normal computes to none, so nothing is generated until you set a real value.
For beginners, treat content as a pseudo-element tool. Setting a string on a regular element does not replace its HTML text the way students often expect.
It is often missing from the accessibility tree. Do not put critical information only in content — put that in HTML.
Write content: attr(data-label) on ::before or ::after to pull an attribute value into generated text.
Strings, none, normal, attr(), counters, and quotes are Baseline and widely available. Alternative text after a slash has limited support. It is a browser CSS property, not a Node.js feature.