Question
How can I use the CSS content property to insert characters that are normally written as HTML entities?
For example, I tried to add a non-breaking space before breadcrumb links with this CSS:
.breadcrumbs a:before {
content: ' ';
}
But instead of rendering a non-breaking space, it displays the literal text . Why does this happen, and what is the correct way to insert that character using CSS?
Short Answer
By the end of this page, you will understand that CSS content does not parse HTML entities like . Instead, it inserts plain text or Unicode characters. You will learn the correct syntax for adding characters in CSS, including non-breaking spaces, arrows, quotes, and separators with pseudo-elements such as ::before and ::after.
Concept
The key idea is that HTML entities belong to HTML, not CSS.
When you write an entity like in HTML, the browser's HTML parser converts it into the corresponding character. But CSS is not parsed as HTML, so content: ' ' is treated as a normal string containing six characters: &, n, b, s, p, and ;.
The CSS content property works differently:
- It can insert plain text strings
- It can insert Unicode characters using escape sequences
- It is usually used with pseudo-elements like
::beforeand::after
So if you want a non-breaking space in CSS, you should use the Unicode value for that character:
content: "\00A0";
Why this matters:
- Developers often use
contentfor icons, separators, labels, and decorative characters - Knowing that CSS uses Unicode escapes helps you avoid confusion with HTML entities
- This is common in navigation, breadcrumbs, form indicators, and UI decorations
In short:
works in HTML\00A0works in CSScontent
Mental Model
Think of HTML and CSS as two different languages speaking to the browser.
- HTML says: "Here is the page structure and text."
- CSS says: "Here is how it should look."
An HTML entity like is a special instruction that only the HTML reader understands.
If you hand that same instruction to CSS, CSS does not translate it. It just treats it as ordinary text.
A useful analogy:
- HTML entities are like words in one language
- Unicode escapes in CSS are like the numeric code for the same symbol
So instead of asking CSS to understand the HTML word , you give it the actual character code \00A0.
Syntax and Examples
The content property is most often used with ::before and ::after.
Basic syntax
selector::before {
content: "text";
}
Insert a non-breaking space
.breadcrumbs a::before {
content: "\00A0";
}
This inserts a Unicode non-breaking space before each breadcrumb link.
Insert a separator arrow
.breadcrumbs a::before {
content: ">";
}
If you just need a normal visible character, you can write it directly.
Insert a bullet using Unicode
.list-item::before {
content: "\2022";
margin-right: 0.5rem;
}
\2022 is the Unicode bullet character.
Insert quotes
.quote::before {
content: "\201C";
}
.quote::after {
content: "\201D";
}
These are opening and closing curly quotes.
Better breadcrumb spacing example
In many cases, you do not need a non-breaking space character at all. Spacing is often better handled with CSS layout properties:
.breadcrumbs a::before {
content: "/";
margin: 0 0.5rem;
}
This is usually clearer and easier to control than inserting spaces as text.
Step by Step Execution
Consider this CSS:
.breadcrumbs a::before {
content: "\00A0";
}
And this HTML:
<nav class="breadcrumbs">
<a href="/home">Home</a>
</nav>
What happens step by step
- The browser reads the HTML and finds an
<a>element inside.breadcrumbs. - The CSS selector
.breadcrumbs a::beforematches that link. - The browser creates a pseudo-element before the link's content.
- It reads
content: "\00A0";. - CSS interprets
\00A0as the Unicode character non-breaking space. - That character is inserted before the word
Home.
What happens with the broken version
.breadcrumbs a::before {
content: " ";
}
Step by step:
- The browser matches the same element.
- It creates the
::beforepseudo-element. - It reads the string
" ". - CSS does not convert HTML entities.
- The exact text
is displayed.
That is why you see the literal entity name instead of a space.
Real World Use Cases
The CSS content property is commonly used for small UI details.
Breadcrumb separators
.breadcrumbs a + a::before {
content: "/";
margin: 0 0.5rem;
}
Adds a separator before every breadcrumb except the first.
Required field markers
label.required::after {
content: " *";
color: red;
}
Displays a red asterisk after required labels.
External link indicators
a.external::after {
content: " \2197";
}
Adds an arrow to show a link opens externally.
Decorative bullets or icons
.feature::before {
content: "\2713";
color: green;
margin-right: 0.5rem;
}
Adds a checkmark before a feature item.
Quotation marks
blockquote::before {
content: "\201C";
}
Useful for styled quotes.
In real projects, this is best for small presentational text or symbols, not important application content.
Real Codebase Usage
In real codebases, developers usually use content in a few predictable patterns.
1. Decorative UI markers
Common for separators, arrows, bullets, and badges.
.nav-item + .nav-item::before {
content: "|";
margin: 0 0.5rem;
}
2. Guarding against extra markup
Instead of adding extra <span> elements just for decoration, developers use pseudo-elements.
.button-download::before {
content: "\2B73";
margin-right: 0.5rem;
}
This keeps HTML cleaner.
3. Using spacing properties instead of space characters
In production code, layout spacing is often done with:
marginpaddinggap- flexbox or grid
Example:
.breadcrumbs {
display: flex;
gap: 0.5rem;
}
This is usually better than injecting spaces with content.
4. Conditional separators with selectors
A common pattern is to avoid adding separators to the first item.
.breadcrumbs a + a::before {
content: "/";
margin-right: 0.5rem;
}
This uses the adjacent sibling selector so only later links get the separator.
5. Accessibility awareness
Teams are careful not to put essential meaning only in ::before or ::after, because pseudo-element content may not be treated the same way in all assistive technology scenarios.
Good rule:
- Use
contentfor decoration or minor labels - Keep important text in the HTML
Common Mistakes
Mistake 1: Using HTML entities in CSS
Broken code:
.notice::before {
content: "©";
}
This prints © literally.
Correct:
.notice::before {
content: "\00A9";
}
Mistake 2: Forgetting quotes
Broken code:
.notice::before {
content: \00A9;
}
Correct:
.notice::before {
content: "\00A9";
}
The content value for text should be in quotes.
Mistake 3: Using :before vs ::before
Older CSS often uses :before, which still works in many cases, but modern CSS prefers ::before.
Preferred:
.item::before {
content: "-";
}
Mistake 4: Using content on normal elements
Broken expectation:
div {
content: "Hello";
}
content does not work like normal text insertion on regular elements. It is mainly for pseudo-elements such as ::before and ::after.
Correct:
div::before {
content: "Hello";
}
Mistake 5: Using text characters for layout spacing
You might try:
.item::before {
content: "\00A0\00A0\00A0";
}
This works, but it is not a good layout technique.
Better:
.item::before {
content: ">";
margin-right: 0.75rem;
}
Use CSS spacing properties for layout whenever possible.
Mistake 6: Putting important content only in pseudo-elements
If the text is essential for meaning, place it in the HTML instead of only in ::before or ::after.
Comparisons
| Concept | Works in HTML | Works in CSS content | Example |
|---|---|---|---|
| HTML entity | Yes | No | , © |
| Plain text string | No special parsing needed | Yes | "Hello", "/" |
| Unicode escape | Not typical in HTML text | Yes | "\00A0", "\2192" |
vs \00A0
| Form | Where to use it | Meaning |
|---|---|---|
| HTML | Non-breaking space entity |
\00A0 | CSS content | Unicode non-breaking space |
::before vs extra HTML
| Approach | When to use it | Pros | Cons |
|---|---|---|---|
::before | Decorative content | Cleaner HTML, easy styling | Not ideal for important content |
| Extra HTML element | Important visible content | Better semantic control | More markup |
Space character vs margin
| Technique | Best for | Recommendation |
|---|---|---|
Inserting spaces with content | Rare text formatting needs | Use sparingly |
margin, padding, gap | Visual spacing and layout | Usually preferred |
Cheat Sheet
Quick rules
- CSS
contentdoes not understand HTML entities - Use
::beforeor::afterwithcontent - Use quoted strings for text
- Use Unicode escapes for special characters
- Use
margin,padding, orgapfor layout spacing instead of inserting many spaces
Common examples
.element::before {
content: "Hello";
}
.element::before {
content: "\00A0"; /* non-breaking space */
}
.element::before {
content: "\2022"; /* bullet */
}
.element::before {
content: "\2192"; /* right arrow */
}
Useful Unicode values
\00A0→ non-breaking space\00A9→ ©\2022→ •\201C→ “\201D→ ”\2192→ →\2713→ ✓
Best practice
.breadcrumbs a + a::before {
content: "/";
margin: 0 0.5rem 0 0;
}
Use symbols for decoration, and use CSS spacing for layout.
FAQ
Why does print as text in CSS?
Because CSS does not parse HTML entities. It treats as an ordinary string.
How do I add a non-breaking space in CSS?
Use the Unicode escape:
content: "\00A0";
Can I use HTML entities like © in CSS content?
No. Use the Unicode equivalent instead, such as "\00A9" for ©.
Should I use :before or ::before?
Use ::before in modern CSS. :before is older syntax that still appears in legacy code.
Is content only for pseudo-elements?
In normal beginner usage, yes. It is mainly used with ::before and ::after.
Is it a good idea to use content for spacing?
Usually no. Prefer margin, padding, or gap for visual spacing.
Can I insert icons with CSS content?
Yes, for simple decorative symbols such as arrows, bullets, or checkmarks. Use Unicode characters or icon fonts if your project uses them.
Mini Project
Description
Create a breadcrumb navigation style that automatically inserts separators between links using CSS pseudo-elements. This project demonstrates the correct use of the content property, avoids HTML entities in CSS, and shows how spacing should usually be handled with margins instead of extra space characters.
Goal
Build a breadcrumb navigation where separators appear automatically between links without changing the HTML for each separator.
Requirements
- Create HTML with at least three breadcrumb links.
- Use
::beforeto insert a separator before every breadcrumb link except the first. - Do not use HTML entities like
in the CSScontentproperty. - Add spacing around the separator using CSS layout or margin.
- Keep the HTML clean and readable.
Keep learning
Related questions
Allow Only Numeric Input (0-9) in HTML Input Using jQuery
Learn how to allow only digits 0-9 in an HTML input using jQuery, with examples, validation tips, common mistakes, and best practices.
Apply CSS !important with jQuery .css()
Learn why jQuery .css() cannot set !important and how to use CSSStyleDeclaration.setProperty() to apply inline important styles safely.
CSS ::before and ::after on Input Elements
Learn why CSS ::before and ::after usually do not work on input elements, what replaced elements are, and practical alternatives.