My blog

Flag Emojis in Windows Browsers

Summary ⇒ Rendering flag emojis in the browser should be straightforward. However, Windows deliberately omits flag emojis from its default fonts, causing browsers to fallback to two-letter country codes instead. Here's an easy and elegant workaround for this issue.


Problem

Windows, as it turns out, does not include Flag emojis in its default fonts.

non_rendering_flags

Initial Flag Emoji Rendering as 2-Letter Country Code.

It took me some time to pinpoint the exact reason for the missing emojis, as other emojis were rendering correctly, and country flags are standard in most use-cases. Initially, I was testing only in Chrome, where some other emojis were rendering correctly. I suspected a CSS or a SvelteKit issue, but when I tested with Firefox and saw the flags, I knew that the problem was somewhere else.

Googling for more specific combinations along the lines of: flags + chrome + windows, produced multiple pages referring to this being a Windows 10+ issue, a problem for which Firefox had a workaround but that other browsers overlooked.

Basic Solution

The main solution suggested is to use PNG images instead of emojis, relying only on basic HTML and CSS. Another suggestion, which I find simple and elegant, came from this post by Frank Prins. Here he proposes the use of custom fonts with emojis for only the flag codes.

Following his explanation this worked just fine. I got to see nice flags everywhere. However, I also got to download 10 MB of fonts, something that could surely be improved.

My Take - Solution Improvements:

Instead of using the whole font file, which is approximately 10 MB, I decided to subset it, which brought the size down to around 830 KB. This subset contains only the flag emojis, which are between the Unicode 1F1E6 and1F1FF.

Here is how

  1. Get the complete font from Noto Emoji

  2. Install the needed python libraries

     pip install fonttools brotli zopfli
    
  3. Create the font sub-set. I am only producing Woff2 as it has 97.8% support rate.

     pyftsubset ./NotoColorEmoji.ttf --unicodes=1F1E6-1F1FF --output-file=Flags.woff2 --flavor=woff2
    

And that is it, now we just add the new font to our project and use it as a font-face.

rendering_flags

Final Flag Emoji Rendering

Final code

Global CSS:

@font-face {
  font-family: 'FlagEmoji';
  unicode-range: U+1F1E6-1F1FF; /* Range for flag emojis */
  src: url("/fonts/Flags.woff2") format('woff2');
}

Example Usage in a SvelteKit Component:

<script>
    let flags = ['🇦🇺', '🇧🇷', '🇨🇦', '🇩🇪', '🇯🇵', '🇮🇳', '🇫🇷', '🇿🇦', '🇪🇸', '🇺🇸'];
</script>

{#each flags as flag, index}

    <span class="emoji-flag" style="font-family: 'FlagEmoji';">{flag}</span>{index < flags.length - 1 ? ' - ' : ''}
{/each}
Carlos Aponte 25 Jan 2024 DIY, SvelteKit