Language of Page and Parts: What WCAG SC 3.1.1 and 3.1.2 Require for Multi-Language E-Commerce Sites
Quietramp ·
Language of Page and Parts: What WCAG SC 3.1.1 and 3.1.2 Require for Multi-Language E-Commerce Sites
Quick answer: WCAG SC 3.1.1 Language of Page
(Level A) requires that “the default human language of each Web page can be programmatically
determined” — in practice, a lang attribute on the <html> element, set to the right BCP 47
code. SC 3.1.2 Language of Parts
(Level AA) goes one level deeper: any passage that switches language from the rest of the page needs
its own lang attribute too, with named exceptions for proper names, technical terms, and words that
have become part of the surrounding language’s vernacular. Both exist for the same reason — so a
screen reader applies the right pronunciation rules instead of reading foreign text as if it were the
page’s default language.
This article covers technical accessibility practice, not legal advice — it explains what WCAG 2.1 AA requires for this pattern and how to meet it, not whether a specific implementation carries legal risk.
Why a lang attribute matters more than it looks
The Understanding doc for 3.1.1 states the mechanism plainly in its Intent section: screen readers need “language information… in order to correctly pronounce that content.” A screen reader running in English mode reads French, German, or Japanese text using English pronunciation rules unless something tells it otherwise — the result isn’t unintelligible exactly, but it’s wrong in a way a sighted user scanning the same page would never notice, because visually the words look fine either way. The same Intent section also flags a second, less obvious beneficiary: browser translation tools and other user agents rely on the same attribute to know what they’re working with. Get the page’s language wrong and both screen readers and “translate this page” features behave incorrectly, for different reasons rooted in the same missing metadata.
3.1.2’s Intent section makes the passage-level case the same way, applied to mixed-language content: “the human language of each passage or phrase can be programmatically determined,” so that a screen reader “can access the language attribute of that passage and switch to that language” for just the part that needs it, then switch back. Neither criterion asks a site to translate anything or judge language quality — both are purely about marking, in code, a fact that’s already true about the content.
SC 3.1.1: one attribute, set once, sitewide
Technique H57, the sufficient technique named in
the Understanding doc, is as narrow as the criterion itself: add a lang attribute to the <html>
element, with a value that’s a real BCP 47 code and actually matches the page’s primary language.
<!-- Fails 3.1.1 — no lang attribute at all -->
<html>
<!-- Fails 3.1.1 — lang is present but wrong; the page is actually in Spanish -->
<html lang="en">
<!-- Passes -->
<html lang="es">
This is a template-level fix, not a per-page one — set it once in the base layout and every page
inherits it, the same pattern as a site-wide <title> template. The failure mode worth watching for
on a multi-region storefront isn’t usually missing — it’s stale: the attribute gets hardcoded once
during initial build and then never touched again, even after a language switcher changes what’s
actually rendered.
SC 3.1.2: marking a passage that isn’t in the page’s main language
Technique H58 is the sufficient technique here:
wrap the specific passage in an element carrying its own lang value, distinct from the page’s
default.
<!-- Page is lang="en"; a customer review quoted in its original French with no markup -->
<p>"J'adore ce sac, la qualité est excellente."</p>
<!-- Passes — the passage carries its own lang, the surrounding page keeps its default -->
<p><span lang="fr">"J'adore ce sac, la qualité est excellente."</span></p>
3.1.2’s own exceptions matter here, quoted directly from the normative text: “proper names, technical terms, words of indeterminate language, and words or phrases that have become part of the vernacular of the immediately surrounding text” don’t need marking. A product named in French, a Latin scientific term in a supplement’s ingredient list, or a word like “boutique” used as ordinary English vocabulary — none of these trigger the requirement. It applies to genuine passages of a different language, not to loanwords or brand names that happen to look foreign.
Where this breaks specifically on e-commerce sites
- A language/region switcher that changes visible copy but not
<html lang>. A shopper picks “Français” from a header dropdown, the storefront’s product names and buttons re-render in French via client-side JavaScript, but the<html>element’slangattribute — set once at build time — stays"en". Everything visible changed; the one attribute a screen reader actually reads didn’t. This is a description-mismatch problem specifically, distinct from the ARIA widget mechanics of the switcher control itself, which Quietramp’s custom dropdown article already covers for country/currency selectors generally. - An embedded foreign-language customer review or testimonial quoted verbatim. A product page
pulls in a genuine review written in the reviewer’s own language and displays it as-is — a real,
common e-commerce pattern, not a hypothetical one, though the specific review text used above is
illustrative, not an actual client’s content. Without a
langwrapper around just that passage, SC 3.1.2 isn’t met even if the rest of the page is marked correctly. - Brand names and loanwords, which need nothing at all. A shoe brand’s French name, or “prêt-à-
porter” used as an English fashion-industry term, falls under 3.1.2’s own exceptions. Marking these
isn’t wrong, but it also isn’t required — worth knowing so a developer doesn’t over-apply
langspans to every foreign-looking word on a page.
Can an automated scanner catch this?
Partly, and the boundary is precise. A direct check of axe-core’s own rule
descriptions
turns up four real rules here: html-has-lang and html-lang-valid (both tagged wcag311) catch a
missing or malformed lang attribute on the <html> element outright, html-xml-lang-mismatch
catches a lang/xml:lang disagreement, and valid-lang (tagged wcag312) checks that any lang
attribute used elsewhere on the page has a syntactically valid value.
What none of these can do is the actual hard part of 3.1.2: notice that a passage of French text has
no lang attribute at all. valid-lang only validates attributes that are already there — it has
no way to read a paragraph, recognize it’s not in the page’s stated language, and flag the missing
markup, because that requires understanding what language the text actually is, not just checking
that a value already on the page is well-formed. A page with a completely unmarked foreign-language
review can score clean on every one of these four rules and still fail SC 3.1.2. This is exactly the
gap a human reviewer closes by reading the page’s actual content, not just its markup.
FAQ
Does adding hreflang tags satisfy this requirement?
No — Google’s own documentation on hreflang
states directly that “Google doesn’t use hreflang or the HTML lang attribute to detect the
language of a page; instead, we use algorithms to determine the language.” hreflang is a
search-engine signal for serving the right regional URL to the right searcher — a separate mechanism
from the lang attribute WCAG 3.1.1/3.1.2 actually require, and having one says nothing about whether
the other exists.
Is 3.1.1 the same requirement as 3.1.2, just stricter? No, they cover different scopes at different conformance levels. 3.1.1 (Level A) is one attribute on the whole document. 3.1.2 (Level AA) is a separate, per-passage requirement that only applies once a page actually mixes languages — a single-language site with 3.1.1 handled correctly has nothing left to do for 3.1.2.
Does a language switcher need to reload the page to pass this?
Not necessarily — a client-side switch is fine as long as it also updates the lang attribute on
<html> (or the relevant passages) to match whatever it just rendered. The requirement is about the
attribute matching the actual content at any given moment, not about how the content gets there.
Get a human-reviewed audit, not just a scan
Automated scanners catch a missing or malformed lang attribute reliably — but an unmarked
foreign-language passage sitting inside an otherwise well-tagged page is invisible to them, because
flagging it means reading the content, not just the markup. Quietramp’s audits pair an automated scan
with a manual review that checks exactly this kind of gap, delivered as a prioritized,
developer-actionable PDF report. See a real sample report or check
pricing — $890 one-time, $99/month for ongoing re-checks after fixes ship.
This article is general accessibility information, not legal advice. Meeting WCAG 2.1 AA does not resolve ADA or any other legal compliance question, and nothing here should be read as a compliance guarantee. Consult qualified counsel for legal risk questions.
This article was drafted with AI assistance and reviewed by a person for accuracy before publication.