Changing Emoji Skin Tones Programmatically

by Adam Davis

Table of contents:

So, you know how many emoji have different skin tones? Emoji skin tones are extremely popular, especially over text and on social media. The raised black fist emoji (✊🏿) was voted “The Most 2020 Emoji” by Emojipedia’s World Emoji Awards.

Each tone is a modifier and many emoji are made up of modifiers and base encodings that map to specific characters. Unfortunately, not every emoji library supports modifiers. But, given their popularity, emoji skin tone modifiers are more than a “nice to have” feature. Plus, they’re a smart way to work because they allow us to write more modular and efficient code.

So that’s what we’re doing in this article: figure out how to work with emoji modifiers programmatically. This way, if you’re ever stuck without skin tone support — or want to create custom variations of other emoji — then you’ll know how!

Meet the Fitzpatrick scale

Skin tone modifiers were officially added to emoji in 2015 as part of Unicode 8.0. They are based on the Fitzpatrick scale, which is a formal classification of human skin tones. The following chart shows how the emoji characters match to Fitzpatrick types:

Skin tone character Fitzptrick type
🏻 1-2
🏼 3
🏽 4
🏾 5
🏿 6

In the simplest use case, when one of these characters is appended to an emoji that supports skin tone modifiers, it will change the skin tone of the emoji.

Another way to say that: 👶 +🏽 = 👶🏽

Applying skin tone modifiers with CSS

To swap between emoji skin tones using CSS, we would start with the base emoji character (👶) and then append the skin tone using the ::after pseudo-selector.

See the Pen emoji-skin-tone-css by Adam (@brew-install-buzzwords) on CodePen.

In addition to using the rendered emoji characters, we could use the Unicode hex codes instead:

See the Pen emoji-skin-tone-css-codepoint by Adam (@brew-install-buzzwords) on CodePen.

Removing and swapping skin tone modifiers with JavaScript

What if the emoji you’re working with has already had a skin tone modifier applied? For that, we’ll need to move beyond CSS. Here’s an example using JavaScript:

See the Pen emoji-skin-tone-js by Adam (@brew-install-buzzwords) on CodePen.

What’s going on here? First, we start with a baby emoji with Fitzpatrick Type 4. We then pass it into the function removeModifier, which searches for any of the skin tone modifiers and removes it from the string. Now that we have the emoji without a modifier, we can add whichever modifier we like.

While this approach works with many emoji, we run into problems when other modifiers are introduced. That’s why we now need to talk about…

Working with ZWJ sequences

Zero width joiner (ZWJ) sequences are like the compound words of Unicode. They consist of two or more emoji joined by the zero width joiner, U+200D.

ZWJ sequences are most commonly used to add gender modifiers to emoji. For example, a person lifting weights, plus ZWJ, plus the female sign, equals a woman lifting weights (️🏋️ + ♀︎ = 🏋️‍♀️).

There’s a few important things to need to keep in mind when working with ZWJ sequences:

Given this information, we need to make the following changes to the previous code example:

See the Pen emoji-skin-tone-js-zwj by Adam (@brew-install-buzzwords) on CodePen.


From this example, you may notice the limitation of consistency. The editor view shows each of the characters in a ZWJ sequence separately, with exception to the skin tone modifiers, which are immediately applied to their corresponding emoji. The console or results views, on the other hand, will attempt render the character for the entire sequence.

Support for this will vary by platform. Some editors may attempt to render ZWJ sequences, and not all browsers will support the same sets of ZWJ sequences.

Additionally, adding skin tones in a ZWJ sequence requires knowing what’s being used as the base emoji. While this would be relatively simple in a situation where the emoji are provided by a known collection, things become more difficult if we want to be able to handle arbitrary input from a user.

Also, be aware that the CSS solutions in this post are not compatible with ZWJ sequences.

Questions to guide development

I put some questions together you may want to ask yourself when you’re designing a system that needs to handle emoji skin tone modifiers:

Hopefully, between the answers to these questions and the examples we’ve looked at here, you’ll have everything you need to support emoji skin tone modifiers in situations where you need them.

This post was originally published on CSS-Tricks

Adam Davis

Share this post: