Screen-reader-friendly Emojis
Emojis. Love them or hate them, they’re part of our online experience. Well for most of us. I was recently messing around with these fun little pictograms and thought “Hey. What do they sound like to a screen reader? Is it possible to make screen-reader-friendly emojis?”
Unsurprisingly, the support for readback was very patchy.
Testing and results
Voiceover (Mac & iOS) and NVDA perfectly read back the emoji character using its CLDR name (with a subtle variation on Voiceover). NVDA even did it right if the emoji wasn’t supported natively on Windows!
JAWS did a passable job. It didn’t support emoji not handled by Windows, and it didn’t use the CLDR name of the emoji consistently. For example, if the fallback emoji for a country flag was just the black waving flag, instead of reading back the intent (e.g. “Flag Wales”), it read back “Black waving flag”. It kind of makes sense, but at the same time, not so much.
JAWS with Firefox and Android’s Talkback with Chromium or Firefox were both complete failures.
Note: Latest OS (with the exception of Android) and browser versions of Edge, Firefox, Safari, and Chromium (Brave or Bromite, not Google’s grabby browser) were tested using this Codepen.
Making it work everywhere
Is it possible to fix this? Yeah, it was, but it was more involved than I expected. At first, I simply tried to add an aria-label with the proper CLDR name. Talkback or JAWS with Firefox wouldn’t pick it up.
<span aria-label="CL button">🆑</span>
Then I tried wrapping the emoji in a div. The first element within was the emoji with aria-hidden to prevent double readback for browsers that could read the stand-alone emoji. The second element was the CSS visually hidden CLDR name. This worked for Talkback and Firefox, but not JAWS and Firefox. It also was visually hideous on focus.
<span>
<span aria-hidden>🆑</span>
<span class="sr-only">CL button</span>
</span>
After re-thinking it one last time, I thought, “Hey, these are really just text-based images!” So finally, after setting the emoji within a span with the role of IMG and an aria-label, every screen reader read it back perfectly. I also suggest appending the word ’emoji’ to the CLDR name, since it’s not inherently clear what this asset actually is. Success!
<span role="img" aria-label="CL button emoji">🆑</span>
There are probably ways to automate the CLDR naming, but yes, it is possible to get screen-reader-friendly emojis everywhere.
I may have enabled a monster. You’re welcome?