squirrelscan
GitHub

lang on elements below html: validating every tag

A quoted passage marked with a bad lang tag is read in the wrong voice. squirrel validates every lang attribute except the one on html.

What lang on an element does

lang on <html> sets the document’s language. lang on any element below it overrides that for its subtree, which is how a French quotation inside an English article gets read with French pronunciation.

WCAG success criterion 3.1.2 Language of Parts, Level AA, asks for it wherever the language changes. An invalid tag is worse than none: it is exposed as given, and what a screen reader does with a tag it cannot resolve is up to the screen reader.

What squirrel checks

One check, valid-lang, at severity warning. It reads every [lang] element except <html>, which a11y/html-lang-valid handles on its own.

A value is accepted when its primary subtag, the part before the first hyphen, is one of the 190 ISO 639-1 codes the rule knows, or is any two or three lowercase letters.

  • Warn with N element(s) with invalid lang attribute. Items read span#quote: lang="english", up to ten with a count of the rest.
  • Pass with All lang attributes are valid, which requires the page to carry lang on more than one element.
  • Info with No additional lang attributes found.

A page with lang only on <html> therefore reports info here, not pass. And because any two or three letter primary subtag is accepted by shape, an invented code such as qq passes. Region and script subtags are not validated at all.

How to fix it

<p>She ended with <span lang="fr">plus ca change</span>.</p>

Use the short code, not the language’s name. lang="french" and lang="en-english" are both invalid, and both are common.

Mark the change where it happens, on the smallest element that contains the foreign text. Marking a whole article when one sentence changes makes the rest of it read wrongly.

Rule IDa11y/valid-lang
CategoryAccessibility
ScopePer-page
Severitywarning
Weight5/10

Enable / disable

Disable this rule

[rules]
disable = ["a11y/valid-lang"]

Disable all Accessibility rules

[rules]
disable = ["a11y/*"]

Enable only this rule

[rules]
enable = ["a11y/valid-lang"]

enable replaces the default ["*"], so this is the only rule selected. Leave disable out: a rule that matches any disable pattern is skipped even when enable names it. Only an enabled setting under a rule’s own [rule_options] table overrides both lists.

Accessibility findings ship in every audit next to the SEO, performance and agent experience rules. See Website security scan with AI for how an agent works through a report.

References

Check your site

Run squirrel audit https://example.com and open the Accessibility section of the report. Each element is listed with the invalid value it carries. Signed-out local audits need no account and cost nothing. Signed-in audits spend credits.

Type to search…

↑↓ navigate↵ openesc close