The lang attribute (WCAG 3.1.1): why it matters and how to set it

Put a lang attribute on the html element and set it to the language tag of the page's main language, such as lang="en" for English or lang="fr" for French. WCAG 3.1.1 (Level A) requires that a page's default language can be programmatically determined, and screen readers can use it to load the right pronunciation rules. Passages in another language get their own lang attribute (3.1.2, Level AA).

Published . Last reviewed .

The lang attribute says which human language a piece of text is written in. On the html element it sets the language of the whole page, because an element with no lang of its own takes the language of its parent (HTML Standard). W3C's Understanding document for 3.1.1 gives the reason: browsers and assistive technology present text more accurately when the language is identified. Screen readers can load the correct pronunciation rules, visual browsers can display characters and scripts correctly, and media players can show captions correctly. The WebAIM Million, an analysis of one million home pages, found a missing document language on 13.5% of them in February 2026, and the fix is one attribute in the template that writes the html tag.

Language is one of the page-level basics, with the page title and the heading structure, that a page needs in its markup. In our reading it rests on the same principle as WCAG 1.3.1: what a reader takes in at a glance has to be in the code for software to use.

Why the language has to be in the code

A reader knows a page is in French. A speech synthesizer does not, unless the markup says so, and when no language is stated anywhere the HTML Standard treats it as unknown. W3C's explanation of 3.1.2 describes what follows when a change of language is not marked: the synthesizer tries to speak the words in the default language it works in, so the French word voiture would be pronounced "voyture" by one that defaults to English. In our reading, a page with no declared language leaves the same guess to the software for every word.

W3C's technique H57 adds that braille translation software can use the declaration to handle accented characters and avoid wrong Grade 2 braille contractions. The 3.1.1 document lists who benefits:

  • people who use screen readers or other technology that turns text into speech;
  • people who find it hard to read written material fluently, such as recognizing characters and alphabets or decoding words;
  • people with cognitive, language and learning disabilities who use text-to-speech software;
  • people who rely on captions for synchronized media.

A wrong value misleads software the same way a missing one does. H57's test procedure asks for two things: that the html element has a lang attribute, and that its value is a valid tag that reflects the primary language of the page. A French page marked lang="en" passes the first test and fails the second.

The attribute labels text. It does not translate it, and it does not set text direction: W3C Internationalization says to use the dir attribute as well for bidirectional text, such as Arabic or Hebrew.

How to set the page language

Put lang on the html element, the first tag after the doctype. H57's example declares a French document; this is a shortened version:

<!doctype html>
<html lang="fr">
<head>
  <meta charset="utf-8">
  <title>...</title>
</head>

Use html and not body. W3C Internationalization notes that the body does not cover the text in the document's head, which includes the title. Then:

  1. Find where the first tag is written. On a hand-built site it is the layout file. In a CMS or site builder, look in the theme or template, and for a site or page language setting that feeds it.
  2. Take the value from the page, not from a constant, on any site with more than one language, so that each translation declares its own.
  3. View the rendered HTML and confirm the value reached the html tag. A setting that exists is not the same as a tag that carries it.

A fix in the base template reaches every page built from it. That layout is also where the landmarks and the skip link live, so one review of it can cover all three.

If a script switches the whole page's language without loading a new document, it must update the attribute too. Every HTML element exposes it as a lang property (see the HTML Standard's HTMLElement interface), so document.documentElement.lang = "de" works. The definition of a web page in the 3.1.1 Understanding document includes a mail program that lives at one address, so in our reading the same rule applies there.

Choosing a valid language tag

The HTML Standard says the value must be a valid BCP 47 language tag, or the empty string. A tag starts with a primary language subtag: en for English, fr for French, de for German, es for Spanish. Optional subtags follow, joined by hyphens. W3C's guide to choosing a language tag says to keep the tag as short as possible and add subtags only when needed to tell the language from something else. It names the IANA Language Subtag Registry as the place to look subtags up.

Values for the html element's lang attribute, whether each works for a page and why
ValueWorks for a page?Why
enYesThe primary subtag for English, and enough unless a regional variant needs to be told apart
en-GB, en-USYesA region subtag separates British from American English. W3C's technique H58 calls the primary code the important part and sub-codes optional, so add one only when it matters
en_USNoSubtags are separated by hyphens, so this is not a valid tag. Write en-US
englishNoNot a subtag in the IANA registry, so the HTML Standard treats it as an unknown language
lang="" or no attributeNoAn empty value means the language is unknown, and so does a page that states it nowhere

Pages with more than one language

Success criterion 3.1.1 asks for the page's default language. The Understanding document defines it as the language used most, or the first language used if several are used equally. Its example is a German page with some English in it: the default language is German, so the html element says de. A site with a French version and an English version has two pages with two defaults, so each version declares its own.

Success criterion 3.1.2 Language of Parts (Level AA) covers the rest: the language of each passage or phrase that differs from the page language must be programmatically determined. The 3.1.1 Understanding document adds that for multilingual sites targeting Level A, the Working Group strongly encourages following 3.1.2 as well.

Marking a passage

Put lang on the element around the text. If there is no element, wrap the text in a span, as W3C Internationalization suggests. The tag you give the span applies to that text only, and the rest of the page keeps the default:

<p>Our <span lang="de">Datenschutzerklärung</span> explains how we handle data.</p>

What does not need marking

The criterion exempts proper names, technical terms, words of indeterminate language, and words or phrases that have become part of the vernacular of the surrounding text. W3C's examples: "Albert Camus" in an English document needs no French marking, and "rendezvous" is a French word that English has adopted. Single words are generally part of the surrounding language unless a change was clearly intended.

Language menus and attribute text

W3C's example for a language switcher writes each link's text as the name of the language in that language, with a matching lang on each link. A version of it:

<ul>
  <li><a href="/de/" lang="de">Deutsch</a></li>
  <li><a href="/fr/" lang="fr">Français</a></li>
</ul>

The attribute also covers an element's text-bearing attributes. If a link's visible text is Spanish but its title is English, lang="es" on the link would mark the title as Spanish too. W3C Internationalization's fix is to leave the link in the page language and put the attribute on a nested span around the Spanish word.

One limit matters when you test with a screen reader. W3C's 3.1.2 document explains that a screen reader's list of links uses each link's accessible name, a flat string with no markup, so a language change inside link text is not exposed there and the voice does not switch. W3C says this is a limit of user agents and assistive technology, outside the author's control, so it does not fail the criterion, and auditors must check the code and not rely only on spoken output. Our guide to how screen readers read a page covers the other views.

Common mistakes

Seven language mistakes, what goes wrong and the fix
MistakeWhat goes wrongFix
No lang on htmlThe language is unknown. W3C's test rule HTML page has lang attribute expects a value, and a failed result means 3.1.1 is not satisfiedAdd it in the template that writes the tag
lang on body onlyThe body does not cover the head, which holds the title, and the test rules look at the html elementMove it to html
An empty or blank valueAn empty value means the language is unknown, and the same rule expects a value that is not empty or only whitespaceSet the tag of the page's language
An invalid tag such as englishThe language is treated as unknown, and a second rule, HTML page lang attribute has valid language tag, expects a known primary language subtagUse a registered subtag, such as en
The wrong language, such as en on a French pageThe software applies the wrong pronunciation rules, and H57's test asks that the value reflect the page's primary language. A value hard-coded into a template shared by every translation causes thisTake the value from each page's own language
Language set only in a meta tag or HTTP headerW3C Internationalization says never to use http-equiv="Content-Language" for this and that the in-page declaration overrides HTTP information. WCAG lists the header only as an advisory techniqueKeep lang on html, and treat any header as extra
xml:lang on its ownIn an HTML document the HTML Standard says it has no effect on language processingUse lang, and give xml:lang the same value if you add it

Two things that look like language settings are not: CSS cannot declare the language of text, and the EN in an old-style doctype names the language of the schema, not the page (both per W3C Internationalization).

Is it required?

Yes, if you aim to meet WCAG. 3.1.1 is a Level A criterion, and the test-rule mapping W3C publishes says it is required for conformance to WCAG 2.0 and later. 3.1.2 is Level AA. Conforming at AA includes every Level A and AA criterion (see conformance levels), so a standard or contract that asks for AA includes both. Our criteria reference lists them.

Which laws apply to you depends on who you are and where you operate: see accessibility laws worldwide, which WCAG version and the questionnaire on which laws apply. This page is general information, not legal advice.

Check it yourself

Checking that the attribute exists takes seconds; confirming that it is right takes someone who can read the language. Work through these in order:

  1. Read the html tag. Open the page source, or the Elements panel in your browser's developer tools, which shows the page after scripts have run. This is W3C's own procedure for H57: the attribute is present, and its value is a valid tag that reflects the primary language of the page.
  2. Run the accessibility bookmarklet on the page as it renders, including pages behind a login. It reports a missing, empty or implausible lang on the html element, meaning a value that does not look like a valid language code.
  3. Scan my site for free to run 16 rule-based checks, one of which flags a page whose html element has no lang attribute or only a blank one, on up to 3 pages.
  4. Check every layout and every language version. A site can have several layouts, each with its own html tag, such as checkout or login. Test one page from each layout and each language.
  5. Listen. Open a page in another language with a screen reader on and listen for words read with the wrong accent or pronunciation. W3C notes that pronunciation quality varies across screen readers and speech synthesizers, so treat what you hear as a prompt to read the code.

Neither the bookmarklet nor the scan can tell whether lang="en" is true of a page written in French, or that a quotation in another language is unmarked, which is the 3.1.2 part. Our page on automated testing coverage explains why checks like these need a person to finish them. The WCAG checklist tracks every Level A and AA criterion, 3.1.1 and 3.1.2 included, and exports CSV.

Keep it checked

The attribute is set once, in a template, and a theme change, a rebuilt layout or a new language version can lose it. GotAlt checks the pages you monitor every week. It compares each image's alt text with the image itself (up to six images per page), runs its rule checks, opens monitored pages in a browser for contrast and other render-dependent checks (see what we check), and reports what changed. Plans are from $69 a month. Audit my whole site from $69/mo.

Language attribute questions

What should the lang attribute be set to?

Set it to the BCP 47 language tag of the language most of the page's text uses, such as en for English, fr for French or de for German. Add a region such as en-GB only when the variant matters, because W3C's advice on choosing a language tag is to keep the tag as short as possible.

Does the lang attribute translate a page?

No. It states which language the text is in and nothing more. Per the HTML Standard, user agents may use it to choose fonts, pronunciations, a dictionary or the interface of controls such as date pickers, but the words on the page stay as written. Translating the content is separate work.

What happens if a page has no lang attribute?

The page does not state its language, so a screen reader has no tag to choose pronunciation rules from. W3C's test rule for success criterion 3.1.1 expects a value on the html element, and a failed result means the criterion is not satisfied. The free scan and the accessibility bookmarklet both flag a missing attribute.

Does every page need its own lang attribute?

Yes. Success criterion 3.1.1 applies to each web page, and in HTML the lang attribute on the html element is the technique W3C documents for it (H57), so every page needs one. Pages built from one template normally share a value, but each translated version needs its own, and a value hard-coded into a shared template gives every translation but one the wrong language.

Should I use en or en-US?

Both are valid. W3C's technique H58 says the primary code is the important part and sub-codes are optional but may help in some circumstances, such as telling British English from American English. If your pages do not need that distinction, en is enough.

Do I have to mark every foreign word on a page?

No. Success criterion 3.1.2 exempts proper names, technical terms, words of indeterminate language and words that have become part of the surrounding language. Mark phrases and passages that are clearly in another language, and treat a single word as part of the surrounding text unless a change of language was clearly intended.

Is a Content-Language header or meta tag enough?

No. W3C Internationalization says to always declare the language with a lang attribute on the html element, never to use a meta element with http-equiv set to Content-Language, and notes that the in-page declaration overrides HTTP information. WCAG lists the HTTP header only as an advisory technique for 3.1.1.

Can a tool check the lang attribute automatically?

Partly. A tool can see whether the attribute exists, is blank, or holds a known language tag. Some also compare the value with the text: W3C's proposed test rule for that counts words and treats a page with no single most common language as inapplicable, so a person still reviews those pages. Passages in another language (3.1.2) need a reader too. GotAlt's scan and bookmarklet check presence and form, not whether the value is true of the text.

Find pages with no language set

The free scan flags a page whose html element has no lang attribute, among 16 rule-based checks on up to 3 pages of your site. It cannot tell whether a value is the right language, so use the steps above for that. No signup.

Scan my site for free