aria-label is a xenophobe

Internationalization is a major component of inclusive design. But with automatic translation features provided by Google and Microsoft, it’s mercifully simple to support — at least at the most basic level. Just include a default language for the page, like lang="en", on the <html> element to give translation services a helping hand.

It’s amazing how many sites don’t do this. I know, because as an accessibility specialist I have to look out for it. If it’s not there, there are certain implications for screen readers and their voice profiles.

Anyway, services like Google’s do most of the heavy lifting by looking for strings and simply translating them. Not as good as a manual translation by a bilingual, human speaker, but surprisingly okay.

The only trouble comes with attributes, and determining which provide strings for users, and which programmatic tokens. While you wouldn’t want aria-pressed="true" to be translated to aria-pressed="vrai", strings intended for human consumption like the value of an aria-label should be covered.

Unfortunately, unlike longstanding attributes marked for assistive technology consumption (alt and title to name a couple), aria-label is ignored by Google’s translator. MS Translate has the same issue, I’m told.

So yeah, aria-label kind of refuses to speak other languages (but, in fairness, it’s not really aria-label‘s fault).

Here are some test cases

(English should be listed as a supported language in Chrome, but not French, for these to work.)


✖️ Not recommended

So, you could use JavaScript to dynamically assign the aria-label based on the page’s lang

const labels = {
  en: 'Submit',
  fr: 'Soumettre',
  es: 'Enviar',
  de: 'Einreichen'

const lang = document.documentElement.lang;

const submit = document.querySelector('[type="submit"]');

submit.setAttribute('aria-label', labels[lang]);

Urgh. That could quickly get unmaintainable when managing a lot of ARIA labels. One thing it does have going for it, though, is more control over the specific translation, so it might be a good way to override automatic translation.

✔️ Recommended

Use aria-labelledby! It refers to an element (which can be hidden if you like) containing a text node, which we know gets translated.

<span id="submit-label" hidden>Submit</span>
<button type="submit" aria-labelledby="submit-label">→</button>

See how the #submit-label element is hidden. This means it won’t be encountered independently of the button by screen readers but, because of the explicit association, it still announces when the button is focused. Good.

✔️✔️✔️ More Recommended

That last approach is a bit complex and contrived. Why not just have a visually hidden <span> inside the button?

<button type="submit">
  <span class="visually-hidden">Submit</span>
  <span aria-hidden="true">→</span>

Note the aria-hidden. Now that an ARIA label isn’t there to override the “→” text node, this symbol would be read out in screen readers (“right arrow”). Using aria-hidden puts a stop to that.


Just use some fucking text. Text that people can see and read and hear in their screen readers all at once. Fucking arrows.