Question

Using CSS content with HTML Entities in CSS

htmlcsshtml-entitiescss-content

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 ::before and ::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 content for 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
  • \00A0 works in CSS content

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.

Take Quiz

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

  1. The browser reads the HTML and finds an <a> element inside .breadcrumbs.
  2. The CSS selector .breadcrumbs a::before matches that link.
  3. The browser creates a pseudo-element before the link's content.
  4. It reads content: "\00A0";.
  5. CSS interprets \00A0 as the Unicode character non-breaking space.
  6. That character is inserted before the word Home.

What happens with the broken version

.breadcrumbs a::before {
  content: "&nbsp;";
}

Step by step:

  1. The browser matches the same element.
  2. It creates the ::before pseudo-element.
  3. It reads the string "&nbsp;".
  4. CSS does not convert HTML entities.
  5. The exact text &nbsp; 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.

Take Quiz

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:

  • margin
  • padding
  • gap
  • 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 content for decoration or minor labels
  • Keep important text in the HTML

Common Mistakes

Mistake 1: Using HTML entities in CSS

Broken code:

.notice::before {
  content: "&copy;";
}

This prints &copy; 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

ConceptWorks in HTMLWorks in CSS contentExample
HTML entityYesNo&nbsp;, &copy;
Plain text stringNo special parsing neededYes"Hello", "/"
Unicode escapeNot typical in HTML textYes"\00A0", "\2192"

&nbsp; vs \00A0

FormWhere to use itMeaning
&nbsp;HTMLNon-breaking space entity
\00A0CSS contentUnicode non-breaking space

::before vs extra HTML

ApproachWhen to use itProsCons
::beforeDecorative contentCleaner HTML, easy stylingNot ideal for important content
Extra HTML elementImportant visible contentBetter semantic controlMore markup

Space character vs margin

TechniqueBest forRecommendation
Inserting spaces with contentRare text formatting needsUse sparingly
margin, padding, gapVisual spacing and layoutUsually preferred
Take Quiz

Cheat Sheet

Quick rules

  • CSS content does not understand HTML entities
  • Use ::before or ::after with content
  • Use quoted strings for text
  • Use Unicode escapes for special characters
  • Use margin, padding, or gap for 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 &nbsp; print as text in CSS?

Because CSS does not parse HTML entities. It treats &nbsp; 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 &copy; 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.

Take Quiz

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 ::before to insert a separator before every breadcrumb link except the first.
  • Do not use HTML entities like &nbsp; in the CSS content property.
  • Add spacing around the separator using CSS layout or margin.
  • Keep the HTML clean and readable.
Take Quiz

Keep learning

Related questions

View more