Who it affects
Someone using a screen reader to read a bilingual village hall notice hears the Welsh paragraph, marked lang="welsh", read with English pronunciation, which turns it into noise.
A Welsh speaker reading on a Braille display gets English contractions applied to Welsh words.
Someone with a learning disability using text to speech to follow along loses the thread when the voice mangles a French quotation in the middle of an article.
Broken versus fixed
The broken markup is shown as code rather than rendered, because the effect is in how it is announced or handled, not how it looks.
<p>The hall is closed on 1 March for St David's Day.</p>
<p lang="welsh">Mae'r neuadd ar gau ar 1 Mawrth ar gyfer Dydd Gŵyl Dewi.</p>
welsh is not a language tag. The screen reader stays in English and reads the Welsh paragraph with English pronunciation.
<p>The hall is closed on 1 March for St David's Day.</p>
<p lang="cy">Mae'r neuadd ar gau ar 1 Mawrth ar gyfer Dydd Gŵyl Dewi.</p>
cy is Welsh. A screen reader with a Welsh voice installed switches to it for this paragraph, then back to English.
Test it by hand in two minutes
- In the Elements panel, search for lang= and read each value. Each must be a two or three letter code, with a hyphen before any region.
- Read the page for text in another language: quotations, names of organisations, menu items, legal phrases. Each run should have its own lang.
- If VoiceOver or NVDA has a voice for that language installed, listen to the section. The voice should change and change back.
- Do not mark single words that English has adopted, such as cafe or rendezvous; they are English now.
The fix
<p lang="welsh">Mae'r neuadd ar gau ar 1 Mawrth.</p>
<p lang="cy">Mae'r neuadd ar gau ar 1 Mawrth.</p>
cy is Welsh, gd Scottish Gaelic, ga Irish, fr French, de German, pl Polish. Region codes are optional and mostly affect pronunciation, for example pt-BR.
Phrase inside a sentence
<p>The sign on the gate reads <span lang="french">Défense d'afficher</span>.</p>
<p>The sign on the gate reads <span lang="fr">Défense d'afficher</span>.</p>
Any element can carry lang. Wrap only the words in the other language.
Language switcher link
<a href="/cy">Cymraeg</a>
<a href="/cy" lang="cy" hreflang="cy">Cymraeg</a>
The link text is in Welsh, so mark it as Welsh. hreflang says what language the destination is in; lang says what the link text is.
Common mistakes
- Using the country, like lang="wales" or lang="ie", instead of the language.
- Marking place names like Llanelli with lang; names are pronounced however the current voice can manage.
- Setting lang on the whole page to the language of one paragraph.
- lang="fr_FR" with an underscore.
WCAG criteria this rule maps to
axe-core tags this rule as WCAG 2.2 level AA. It is one of the checks for:
- 3.1.2 Language of Parts (level AA). Official W3C text.
The scanner checks every lang attribute below the html element for a well-formed tag with a known language. It cannot see text in another language that has no lang at all, and it cannot tell whether the code names the right language. Automated tools find only part of the accessibility problems on a page; a pass on this rule is not a pass on the criterion.
Related rules
html-has-lang
The lang attribute on the html element tells browsers and screen readers which language the page is written in.
A
The page language code must be valid
html-lang-valid
A lang attribute only works if its value is a real language tag: a two or three letter code like en, cy or fr, optionally followed by a hyphen and a region, like en-GB.
A
lang and xml:lang must name the same language
html-xml-lang-mismatch
Some pages, usually ones generated as XHTML or from older templates, carry both a lang attribute and an xml:lang attribute on the html element.