Sometimes the same emoji-capable Unicode character appears as a plain text symbol in one place and as an emoji-style symbol somewhere else.
Two invisible characters are used in assigned emoji variation sequences to request that presentation choice:
- U+FE0E VARIATION SELECTOR-15 (VS15) requests text presentation;
- U+FE0F VARIATION SELECTOR-16 (VS16) requests emoji presentation.
Neither selector normally displays a glyph of its own. In a valid variation sequence, it modifies the requested presentation of the character immediately before it.
VS15 and VS16 at a Glance
| Code point | Name | Short name | Request |
|---|---|---|---|
| U+FE0E | VARIATION SELECTOR-15 | VS15 | Text presentation |
| U+FE0F | VARIATION SELECTOR-16 | VS16 | Emoji presentation |
Both are part of the wider family of invisible and special space characters. Unicode also classifies variation selectors as default-ignorable code points, which describes their fallback display behavior—not whether they are meaningful.
What Does VS15 Do?
VS15 asks for the text presentation of an eligible preceding emoji character.
Conceptually, the sequence is base character + U+FE0E.
If that pair is one of Unicode’s assigned text presentation sequences and the renderer supports it, the character is shown using a text-style presentation rather than an emoji-style one.
“Text presentation” doesn’t promise one exact black-and-white glyph across every device. Fonts and rendering systems can still differ.
What Does VS16 Do?
VS16 asks for the emoji presentation of an eligible preceding emoji character.
Conceptually: base character + U+FE0F.
If that pair is an assigned emoji presentation sequence and the platform supports it, the renderer should use the emoji-style presentation defined for that sequence.
The VS16 itself stays invisible. What changes is the presentation of the preceding character.
They Don’t Work With Every Character
This is the most important limitation.
VS15 and VS16 aren’t general styling commands. You can’t append one to any Unicode character and expect a standardized text or emoji version to appear.
Unicode defines specific assigned variation sequences. For emoji, the valid text and emoji presentation sequences are listed in the Unicode emoji data.
If a base-plus-selector pair isn’t assigned, a conforming implementation doesn’t get to invent a special presentation for it.
What If the Sequence Isn’t Supported?
If the sequence is unassigned or the implementation doesn’t support the assigned variant, Unicode’s fallback is straightforward: display the base character as though the variation selector weren’t there, and normally keep the selector itself invisible.
That’s why a selector can still be present in the underlying text even when you can’t see any presentation difference.
Why Can the Same Symbol Look Different After Copying It?
Several things can affect the result: the character’s default presentation, whether VS15 or VS16 is present, whether Unicode defines that sequence, whether the font supports it, and how the platform renders emoji.
Some emoji presentation sequences are encoded as a base character followed by VS16. When you copy the displayed symbol, you can copy both code points even though the screen looks like it contains only one symbol.
So if a symbol suddenly becomes emoji-style—or falls back to text-style—after you paste it somewhere else, the font isn’t always the whole story. The selector may be part of the text. That’s another example of why why copied text can contain invisible characters.
VS16 Is Not ZWJ
VS16 and ZWJ are both invisible and both can appear in emoji-related text, but they do different jobs.
| Character | Main role |
|---|---|
| U+FE0F VS16 | Requests emoji presentation in an assigned sequence |
| U+200D ZWJ | Participates in joining or combined sequences, including emoji ZWJ sequences |
An emoji sequence can contain both kinds of controls in different positions. Zero Width Space vs Zero Width Joiner vs Zero Width Non-Joiner explains how ZWJ differs from other zero-width controls.
What About Search, Matching, and Normalization?
At the raw sequence level, a base character by itself and the same base followed by U+FE0F aren’t identical.
On the other hand, Unicode says applications that don’t support variation sequences should generally behave as though the selector weren’t present for processes such as searching, sorting, and parsing. A normal search may therefore ignore a distinction that a code-point inspector still shows.
Standard Unicode normalization doesn’t remove VS15 or VS16. Variation sequences are designed to remain stable under normalization, so if an application wants the selectors to be irrelevant for a particular comparison, that has to be part of its matching policy.
Should You Remove a Variation Selector?
Only if you know the presentation distinction isn’t needed.
Removing VS16 can change an emoji-style request back to the base character’s default behavior. Removing VS15 can do the same in the other direction.
If the selector is part of deliberately encoded content, deleting it can change what a user sees.
How Can You Detect VS15 or VS16?
Inspect the code points and look for:
- U+FE0E — VARIATION SELECTOR-15;
- U+FE0F — VARIATION SELECTOR-16.
Don’t rely only on whether the symbol looks colorful. Rendering can differ between platforms. How to Find and Remove Invisible Unicode Characters Without Breaking Text covers a safer inspection-first workflow for invisible characters.
The Main Difference
VS15 requests text presentation. VS16 requests emoji presentation.
They have standardized presentation effects only in assigned variation sequences. If the sequence isn’t supported, the base character normally falls back to its ordinary display and the selector stays invisible.
So when two encoded versions of a symbol behave differently as text or emoji, checking for U+FE0E or U+FE0F is a useful place to start.