How to prevent Unicode characters from rendering as emoji in HTML from JavaScript?

Append the Unicode variation selector character for forcing text, VS15, ︎.
This forces the previous character to be rendered as text rather than as an Emoji Symbol.

<p>🔒&#xFE0E;</p>

Result: 🔒︎

Learn more at: Unicode symbol as text or emoji


I had a Unicode character in the content of a span::before, and I had the font-family of the span set to "Segoe UI Symbol". But Chrome used "Segoe UI Emoji" as the font to render it.

However, when I set the font-family to "Segoe UI Symbol" explicitly for the span::before, rather than just for the span, then it worked.


For a CSS-only solution to prevent iOS displaying emojis, you can use font-family: monospace which defaults to the text variant of the glyph rather than the emoji variant.


If your primary concern is forcing monochromatic display so the emoji don't stand out from the text too much, CSS filters, either alone or in combination with the Unicode variation selector, may be something you want.

p.gscale { 
  -webkit-filter: grayscale(100%);
  filter: grayscale(100%);
}
a {
  color: #999;
  -webkit-filter: grayscale(100%) sepia(100%) saturate(400%) hue-rotate(170deg);
   filter: grayscale(100%) sepia(100%) saturate(400%) hue-rotate(170deg);
}
<p class="gscale">You've now got emoji display on 🔒lockdown🔒.</p>

<p>External Link: <a href="https://knowyourmeme.com/memes/party-hard">celebrate 🎉</a></p>

Unlike the variation selector, it shouldn't matter how the emoji are rendered, because CSS filters apply to everything. (I use them to grayscale PNG-format "link type" icons on hyperlinks that have been modified to point to the Wayback Machine.)

Just mind the caveat. You can't override a parent element's filter in a child, so this technique can't be used to grayscale a paragraph, then re-colorize the links within it. 😢

...still, it's useful for situations where you're either going to be making the whole thing a hyperlink or disallowing rich markup within it. (eg. titles and descriptions)

However, this won't work unless CSS actually gets applied, so I'll give a second option which is more reliable in <title> elements than the Unicode variation selector (I'm looking at you GitHub. I don't like fake icons in my browser tabs):

If you're putting a user-provided string into a <title> element, filter out the emoji along with any bold/italic/underline/etc. markup. (Yes, for those who missed it, the standard does call for the contents of <title> to be plain text aside from the ampersand escapes and the browsers I tested all interpret tags within as literal text.)

The two ways I can think of are:

  1. Directly use a manually-maintained regex which matches the blocks where the newest version of Unicode puts its emoji and their modifiers.
  2. Iterate through the grapheme clusters and discard any which contain recognized emoji codepoints. (A grapheme cluster is a base glyph plus all the diacritics and other modifiers which make up the visible character. The example I link to uses Python's regex engine to tokenize and then the emoji package for the database, but Rust is a good example of a language where iterating grapheme clusters is quick and easy via a crate like unicode-segmentation.)

None of the other solutions worked for me but I eventually found something that did courtesy of css-tricks. In my use case, I was adding a link symbol at the end of each markdown header for direct linking to sections within articles but the emoji symbol looked a bit distracting. The following code allowed me to make the emoji look like a plain symbol and then switch back to looking like an emoji when hovered over which was perfect for my use case. If you just want to make the icon look more like a symbol just change the text-shadow hexadecimal color to #000 as shown in the second example.

.direct-link {
  color: transparent;
  text-shadow: 0 0 #dbe2ec;
}

.direct-link:hover {
  color: inherit;
}
<h3>Blog Subheading<a href='#' class="direct-link">🔗</a></h3>

   .direct-link {
      color: transparent;
      text-shadow: 0 0 #000;
    }
    <h3>Blog Subheading<a href='#' class="direct-link">🔗</a></h3>