Make WordPress Core

Opened 8 months ago

Last modified 8 months ago

#37486 new defect (bug)

Make emojis accessible

Reported by: afercia Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version: 4.2
Component: Emoji Keywords: has-screenshots
Focuses: ui, accessibility, javascript Cc:


Splitting this out from #37432.

Currently, the WordPress Emojis are not accessible. The alt text contains the emoji character (vs a HTML encoded entity, or the emoji description) and that's a deliberate implementation choice, see 37433#comment:3 intended to allow copy and pasting the emojis.

We've discussed a bit this issue in the accessibility weekly meeting and agreed there's room for improvements. At least, starting a discussion about emojis accessibility would be very welcome.

Quickly checking how screen readers announce the WordPress emojis, there's no accessible name or description they can use:


Note: VoiceOver reads out "group" because the image is a svg file.

Just adding an aria-label attribute (I've quickly edited in the browser console) gives screen readers an accessible name to announce:


Comparing with what others do, for example Twitter because they usually have great solutions for accessibility, they use png images and both an aria-label and a title attribute, so VoiceOVer in this example reads out both. I guess the title attribute is used just to show the browser's "tooltip" with the emoji name:


<img class="Emoji Emoji--forText" src="https://abs.twimg.com/emoji/v2/72x72/1f60e.png" 
 draggable="false" alt="" title="Smiling face with sunglasses" aria-label="Emoji: Smiling face with sunglasses">

The aria-label solution is mentioned also on a related issue on the twemoji GitHub: https://github.com/twitter/twemoji/issues/41

Change History (8)

#1 @dd32
8 months ago

Loading descriptions client-side of all emoji's is unlikely to be a solution which we can use, simply due to the sheer size of emoji's and the lengths of their translations (which also then need to be translated).

Can we make it display the Emoji itself to screen readers instead of group? (Which was also an intention I believe) We'll then be throwing emoji descriptions into the ball court of screen readers though (many of which may not support the full emoji language for quite some time)

#2 @peterwilsoncc
8 months ago

For the SVG copies (used by 97% of web traffic) is there a server side solution we could implement by adding the descriptions to the SVGs on the CDN?

@afercia how do screen readers handle native emoji?

#3 @afercia
8 months ago

Screen readers usually read out what browsers expose to them through their accessibility APIs. Sometimes, in limited circumstances, they try to read directly the DOM to work around known browsers inabilities to correctly expose accessible properties. So it's mostly a matter of platform/browsers support for unicode/svg and how browser expose these informations to assistive technologies. However, WordPress is not using inline SVGs. These are just standard <img> elements with no textual alternative whatsoever.

As per the group thing, seems specific to Safari+VoiceOver and I think just adding a role="img" attribute could help the emojis to be correctly identified as images. Quick test available on this codepen: http://s.codepen.io/afercia/debug/wWXQao


Native support:
interestingly, VoiceOver announces the WP Emojis skin tone modifier as "Emoji modifier fitzpatrick type" and displays it in the Caption Panel:


hearing just "Emoji modifier fitzpatrick type" is a bit annoying and not useful at all, one more reason to provide a textual alternative in my opinion. This made me curious though so I've tested a bit more. Seems Safari+VoiceOver on OS X El Capitan can correctly announce the native emoji characters. I guess no surprise, since this platform has a very good support for Unicode. By the way, it seems they're often announced with a slightly different name, for example "Station" is announced as "Subway station" and this happens in many, many, other cases:


Unfortunately, on other platforms support greatly varies across browsers even for common Unicode characters, see the test for the "right-pointing double angle quotation mark" on the codepen. In the worst case, emojis are announced as "symbol" and then an alphanumeric string (often different from the character code).

Descriptions size/Translations:
yep, I can understand the technical challenge. I really have no idea about the current implementation details :) About translations, maybe there are already some translations available? See below:


#4 @afercia
8 months ago

about supported/unsupported emoji versions, Safari+VoiceOver announce the supported one:

the first one in this example is announced as "slightly smiling face". Setting VoiceOver in a different language, for example Italian, works and the emoji is announced as "Faccina leggermente sorridente". Nope for the unsupported version 9 fallback to image though.

This ticket was mentioned in Slack in #accessibility by afercia. View the logs.

8 months ago

#6 @rianrietveld
8 months ago

  • Milestone changed from Awaiting Review to Future Release

#7 @pento
8 months ago

I've been thinking about this a little bit, and I think I have a direction worth investigating.

  • First, change the emoji element from an img to an object. This allows the SVG to interact with the embedding window. (The CDN currently doesn't allow embedding this way due to X-Frame-Options, but that can be fixed.) In the mean time, here's an SVG with the below script added, and no X-Frame-Origins restrictions.
  • Modify all of the SVGs to add a little bit of JavaScript. Something like:
<script type="text/javascript">
    window.parent.postMessage( { description: 'Rainbow flag', emoji: '1f3f3-fe0f-200d-1f308.svg' }, '*' );
  • Listen for this message in wp-emoji.js:
window.addEventListener( 'message', descriptionListener, false ):
function descriptionListener( event ) {
    // Check that the message is coming from the CDN, and is correctly formatted.

    // Find all emoji elements that match event.data.emoji

    emojiEl.setAttribute( 'title', event.data.description );
    emojiEl.setAttribute( 'aria-label', 'Emoji: ' + event.data.description );

This idea has several weaknesses:

  • It only works for SVG embeds, not PNG embeds. That excludes IE 8 and earlier.
  • To be properly translatable, we'd need to have different files for each language. It's not practical to update a single SVG file each time a new translation is added, due to the way the CDN works. Effectively, we'd have 1f3f3-fe0f-200d-1f308.en_AU.svg, 1f3f3-fe0f-200d-1f308.it_IT.svg, etc. I'm not sure whether we'd load emoji by site language or user client language, but that's an easy argument to have. :-)
  • It updates the DOM twice - once to add the emoji image, once to add the aria-label. I don't know how this affects screen readers.
  • Adding the title attribute doesn't cause a hover tooltip on object elements. I don't know how the aria-label behaves.
  • I don't know if this would be accepted by the upstream Twemoji project. It's unlikely that we'd need to change twemoji.js, so the primary concern is additional maintenance when emoji need to be updated - we'd need a script to add the <script> to all of them. Also, Twitter may not share their translations, so we may need to add all of the strings to GlotPress.

Finally, here are some things that don't work, while I was experimenting:

  • Embedding as an img. The SVG can't send the message.
  • Accessing the SVG DOM from the parent window, so that we don't need to do the postMessage. Cross Domain Origin restrictions.

This ticket was mentioned in Slack in #accessibility by afercia. View the logs.

8 months ago

Note: See TracTickets for help on using tickets.