Special characters in CSS generated content (::before, ::after)

If you do CSS, you may be familiar with the ::before pseudo-element.  Have you ever tried using it to insert an unusual character?  I did today, and it took about 20 minutes to figure it out.  Here’s here to do it.

See, you can’t use an HTML/XHTML entity like this, because it actually inserts the ampersand and all:

#metaInfo::before {
  content: "⇓"; /* No!*/
  display: inline;
}

It turns out you have to put in an escaped reference to the Unicode code point in hexadecimal notation. (Keep reading if this is confusing.)

#metaInfo::before {
  content: "\21D3"; /* Downwards Double Arrow (⇓) */
  display: inline;
}

The fact you cannot use HTML entities in generated content does not seem to be spelled out in the W3C specs, though it is hinted at in the section on generated content.

If you know the symbol you want, and/or its HTML entity, how do you get the Unicode hexadecimal code point? There is a crazy simple way to turn an HTML entity into a CSS-escaped Unicode code point. Just go to the r12a Unicode code converter. Type or paste what you have in the appropriate box and click “Convert.” All the other Unicode conversions you could ever want will instantly appear! It’s great!

Now, I originally wrote this page in 2005. Since then, Unicode has become a lot more standard and universal as a character set. So assuming your editor is saving in the UTF-8 encoding, you can simply use the desired Unicode symbol verbatim:

#metaInfo::before {
  content: "⇓";
  display: inline;
}

Have you ever tried to use a nice Unicode symbol only for it to show up as an unwanted emoji (especially on a mobile phone)? Well, this is because the Unicode Consortium made a big mistake. (Ask me to blog about this and add a link here to explain it!) The good news is that you can fix it. Any symbol that you want to display as a regular symbol instead of a color emoji, just follow with \FE0E in CSS or ︎ in HTML. So here is what our double down arrow looks like in CSS with this anti-emoji protection added:

#metaInfo::before {
  content: "\21D3\FE0E"; /* Downwards Double Arrow (⇓)*/
  display: inline;
}

By the way, if you want the opposite, that is, for a symbol to be displayed as an emoji whenever possible, append \FE0F in CSS or ️ in HTML.

FYI: Some people use :before instead of ::before.  While the W3C may have been ambiguous about this type of thing in the past, it is now understood that :foo represents a pseudo-class and ::foo represents a pseudo-element. If you are using generated content, you are dealing with a pseudo-element and should use the double-colon syntax.


December 10th, 2005. (Updated: April 08, 2022 at 10:36pm.)
Alan Hogan (@alanhogan_com).  Contact · About