The lang attribute declares what natural language an HTML element's content is in. It serves two distinct WCAG criteria:
WCAG 3.1.1 (Level A) -- Language of Page: The <html> element MUST have a lang attribute declaring the document's primary language. Without it, screen readers default to the user's system language regardless of what the page actually contains -- producing French phonetics on English text, etc.
<html lang="en">
WCAG 3.1.2 (Level AA) -- Language of Parts: When content shifts language mid-page (a quote in another language, a foreign loanword, a section in a second language), the language change should be marked with a lang attribute on the surrounding element.
<html lang="en">
<body>
<p>The German term <span lang="de">Schadenfreude</span> means...</p>
<blockquote lang="fr">Vive la France!</blockquote>
</body>
</html>
The screen reader switches pronunciation when entering each lang-marked subtree, so the user hears proper language pronunciation throughout the page.
Tag values follow BCP 47:
- Primary subtag (lowercase):
en,fr,de,ar,zh - Optional region (uppercase):
en-US,en-GB,pt-BR,zh-CN - Optional script (Title case):
zh-Hans(Simplified),zh-Hant(Traditional)
Common bugs:
- Missing on
<html>entirely -- WCAG 3.1.1 fail; screen readers can't pronounce content correctly. lang=""(empty value) -- some CMSes strip the value; treated as missing.- Wrong format like
lang="english"(full word) orlang="en_US"(underscore) -- silently ignored by browsers; falls back to default behavior. - Mixed-language content with no per-element lang attributes -- screen readers pronounce the foreign content with wrong phonetics. Easily fixed by adding
<span lang="X">...</span>around each foreign segment.
The BeaverCheck i18n-extras analyzer specifically detects subtree lang attributes (a positive signal of WCAG 3.1.2 compliance) and surfaces RTL pages missing the dir="rtl" attribute (a related layout bug).