Question
How can you use the CSS content property to insert characters that are normally written as HTML entities?
For example, why does this CSS display the literal text instead of inserting a non-breaking space?
.breadcrumbs a::before {
content: ' ';
}
What is the correct way to insert a non-breaking space or similar special character with CSS content?
Short Answer
By the end of this page, you will understand that CSS content does not parse HTML entities like . Instead, CSS inserts plain text strings or Unicode characters. You will learn how to add special characters correctly using direct characters or Unicode escape sequences such as "\00a0".
Concept
CSS and HTML are parsed differently.
HTML entities like , &, and © are part of HTML syntax, not CSS syntax. That means the CSS content property does not interpret as a non-breaking space. It sees it as an ordinary string of characters and prints it exactly as written.
For example:
content: ' ';
This means:
- start a string
- place the characters
&,n,b,s,p,; - end the string
So the browser displays literally.
To insert special characters with CSS content, use one of these approaches:
- type the actual character directly, if appropriate
- use a Unicode escape sequence such as
"\00a0"for a non-breaking space
Mental Model
Think of HTML entities as a language that HTML understands, but CSS does not.
- HTML sees
and translates it into a special space. - CSS sees
inside quotes and treats it like a normal word.
A simple analogy:
- HTML entities are like commands written for one machine.
- CSS
contentis a different machine with different commands. - If you send an HTML command to CSS, CSS does not translate it. It just prints it.
So when using content, think in terms of:
- plain text strings
- Unicode characters
- Unicode escape codes
not HTML entities.
Syntax and Examples
The basic syntax for content with pseudo-elements looks like this:
selector::before {
content: "text";
}
selector::after {
content: "text";
}
Example 1: Insert a normal string
.note::before {
content: "Note: ";
}
This adds the text Note: before the element.
Example 2: Insert a non-breaking space
.breadcrumbs a::before {
content: "\00a0";
}
\00a0 is the Unicode code point for a non-breaking space.
Example 3: Insert a separator with spacing
.breadcrumbs a + a::before {
content: ;
}
Step by Step Execution
Consider this CSS:
.breadcrumbs a + a::before {
content: "\00a0>\00a0";
}
And this HTML:
<nav class="breadcrumbs">
<a href="/">Home</a>
<a href="/products">Products</a>
<a href="/products/shoes">Shoes</a>
</nav>
What happens step by step
- The browser finds every
ainside.breadcrumbs. - The selector
a + amatches every link that comes immediately after another link. - That means:
Homeis not matched
Real World Use Cases
Developers use CSS content for many small interface details.
Breadcrumb separators
.breadcrumbs a + a::before {
content: " / ";
}
Useful for navigation trails.
Required form labels
.required label::after {
content: " *";
color: red;
}
Adds a visual required marker.
External link indicator
a.external::after {
content: " ↗";
}
Shows that a link opens an external resource.
Quotes or decorative marks
blockquote::before {
content: "\201C";
}
Adds an opening quotation mark.
Real Codebase Usage
In real projects, developers usually use CSS content for small presentational additions rather than meaningful data.
Common patterns
Visual separators
.breadcrumbs li + li::before {
content: " / ";
color: #666;
}
This avoids adding separator markup into every breadcrumb item.
Icons with Unicode characters
.download-link::before {
content: "\2193 ";
}
Good for lightweight decorative icons.
Guarding the first item
Instead of adding a separator before every item, developers often use selectors like:
.item + .item::before {
content: ", ";
}
This is similar to a guard clause in programming: only apply the separator when there is a previous item.
Keeping content decorative
Teams usually avoid placing essential business information only in or , because generated content may not be as reliable for accessibility, translation, or copy/paste workflows.
Common Mistakes
1. Using HTML entities in CSS strings
Broken example:
.box::before {
content: "©";
}
This prints © literally.
Correct:
.box::before {
content: "\00a9";
}
or
.box::before {
content: "©";
}
2. Forgetting to use a pseudo-element
Broken example:
.box {
content: "Hello";
}
For normal elements, content does not work the way beginners often expect.
Correct:
.box::before {
content: ;
}
Comparisons
| Approach | Works in CSS content? | Example | Notes |
|---|---|---|---|
| HTML entity | No | " " | Printed literally in CSS |
| Direct character | Yes | "©" | Easy to read if encoding is reliable |
| Unicode escape | Yes | "\00a9" | Best when you want explicit, portable character insertion |
| Regular text string | Yes | "Hello" | Most common use |
::before vs ::after
Cheat Sheet
Quick rules
- CSS
contentdoes not understand HTML entities like - Use
::beforeor::after - Use quoted strings for text
- Use Unicode escapes for special characters
- Prefer HTML for important content
Common syntax
.element::before {
content: "Hello";
}
.element::before {
content: "\00a0";
}
Useful Unicode values
- Non-breaking space:
\00a0 - Copyright:
\00a9 - Right arrow:
\2192 - Opening double quote:
\201C - Closing double quote:
\201D - Bullet:
\2022
Example fixes
FAQ
Why does print literally in CSS?
Because is an HTML entity, and CSS does not parse HTML entities inside content strings.
How do I insert a non-breaking space in CSS?
Use a Unicode escape:
content: "\00a0";
Can I type the actual special character directly in CSS?
Yes. For many characters, you can write them directly, such as © or a real non-breaking space, but Unicode escapes are often clearer.
Should I use :before or ::before?
Use ::before in modern CSS. :before is older syntax but still widely supported.
Is CSS-generated content good for accessibility?
It can be acceptable for decorative content, but important information should usually be in the HTML.
Can I add icons using CSS content?
Yes. You can use Unicode symbols or icon fonts, but simple Unicode characters are often the easiest option.
Does content work on normal elements without pseudo-elements?
Mini Project
Description
Build a breadcrumb navigation style that inserts separators between links using CSS generated content. This demonstrates the correct way to add visual characters in CSS without using HTML entities like .
Goal
Create breadcrumb links that display a separator before each item except the first, using ::before and valid CSS content values.
Requirements
- Create a breadcrumb navigation with at least three links.
- Add separators using CSS
::beforeinstead of putting separator text in the HTML. - Do not show a separator before the first breadcrumb item.
- Use either plain text separators or Unicode escapes in the
contentproperty. - Keep the HTML clean and readable.
Keep learning
Related questions
Angular ngClass Conditional Class Binding Explained
Learn how to use Angular ngClass for conditional classes, fix common binding mistakes, and understand why this template error happens.
CSS :not() Selector for Elements Without a Class or Attribute
Learn how to use the CSS :not() selector to target elements that do not have a specific class or attribute, with examples and common pitfalls.
CSS Font Scaling Relative to Container Size: %, em, rem, vw, and Responsive Text
Learn how CSS font scaling really works and how to make text responsive using %, em, rem, vw, clamp(), and media queries.