HTML Guides for lang
Learn how to identify and fix common HTML validation errors flagged by the W3C Validator — so your pages are standards-compliant and render correctly across every browser. Also check our Accessibility Guides.
The W3C HTML Validator reports this error when it encounters isolang on the <html> element because isolang is not a recognized attribute in any version of HTML. This typically happens when developers attempt to specify the document’s language but use an incorrect or made-up attribute name, possibly confusing it with ISO language code terminology.
The correct attribute for declaring a document’s language is lang. This attribute accepts a valid BCP 47 language tag, which in most cases is a simple two-letter ISO 639-1 code (like en for English, fr for French, or pt for Portuguese). You can also use extended subtags for regional variants, such as en-US for American English or pt-BR for Brazilian Portuguese.
Setting the lang attribute properly is important for several reasons:
- Accessibility: Screen readers use the lang attribute to select the correct pronunciation rules, ensuring content is read aloud accurately.
- SEO: Search engines use the language declaration to serve the right content to users based on their language preferences.
- Browser behavior: Browsers rely on lang for features like spell-checking, hyphenation, and selecting appropriate default fonts for the given language.
- Standards compliance: Only recognized attributes pass W3C validation, and valid markup ensures consistent, predictable behavior across browsers.
To fix this issue, simply replace isolang with lang on your <html> element. Keep the same language code value—it’s the attribute name that’s wrong, not the value.
Examples
❌ Incorrect: Using the invalid isolang attribute
<!DOCTYPE html>
<html isolang="pt">
<head>
<title>Minha Página</title>
</head>
<body>
<p>Olá, mundo!</p>
</body>
</html>
This triggers the error: Attribute “isolang” not allowed on element “html” at this point.
✅ Correct: Using the lang attribute
<!DOCTYPE html>
<html lang="pt">
<head>
<title>Minha Página</title>
</head>
<body>
<p>Olá, mundo!</p>
</body>
</html>
✅ Correct: Using a regional language subtag
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<title>Minha Página</title>
</head>
<body>
<p>Olá, mundo!</p>
</body>
</html>
Common language codes
Here are some frequently used ISO 639-1 language codes for the lang attribute:
- en — English
- es — Spanish
- fr — French
- de — German
- pt — Portuguese
- zh — Chinese
- ja — Japanese
- ar — Arabic
- ko — Korean
- ru — Russian
The value en-EN is not a valid language tag for the hreflang attribute on a link element.
The hreflang attribute specifies the language (and optionally, the region) of the linked resource to help search engines and browsers deliver the correct localized version. Language tags should follow BCP 47 standards, with primary language subtags (like en) and optional region subtags (like US). A correct region subtag for English would be en-US (English as used in the United States) or en-GB (United Kingdom). Double language subtags like en-EN are invalid because the region subtag must be a valid country code, not a repeat of the language code.
Correct usage:
<link rel="alternate" href="https://example.com/en/" hreflang="en">
<link rel="alternate" href="https://example.com/en-gb/" hreflang="en-GB">
<link rel="alternate" href="https://example.com/en-us/" hreflang="en-US">
Incorrect usage:
<link rel="alternate" href="https://example.com/en-en/" hreflang="en-EN">
Use en, en-US, or en-GB as appropriate for English-language content, but never en-EN.
The lang attribute on the <html> element tells browsers, screen readers, and search engines what language the page content is written in. Its value must follow the BCP 47 standard, which uses ISO 639 language codes as the primary language subtag. When the validator reports that a language subtag “is not a valid ISO language part of a language tag,” it means the code you provided doesn’t match any recognized language in the ISO 639 registry.
Common Causes
Typos in the language code
A simple misspelling like emg instead of en, or fre instead of fr, will trigger this error.
Using a country code instead of a language code
Country codes (ISO 3166) and language codes (ISO 639) are different standards. For example, uk is the country code for the United Kingdom, but it’s also the valid language code for Ukrainian. Using gb (Great Britain) as a language would be invalid. Similarly, us is not a language code — you need en for English or en-US for American English specifically.
Using made-up or deprecated codes
Codes like xx, en-UK, or other non-standard values will fail validation. Note that while en-US and en-GB are valid (language-region format), en-UK is not because UK is not the correct ISO 3166-1 region subtag for the United Kingdom — GB is.
Why This Matters
- Accessibility: Screen readers rely on the lang attribute to select the correct pronunciation rules and voice profile. An invalid language code can cause assistive technology to mispronounce content or fall back to a default language.
- SEO: Search engines use the lang attribute as a signal for serving the right content to users in the appropriate language and region.
- Browser behavior: Browsers use the language tag for spell-checking, hyphenation, font selection, and other language-sensitive rendering decisions.
How to Fix It
- Identify the language your page is written in.
- Look up the correct ISO 639-1 two-letter code (preferred) or ISO 639-2 three-letter code for that language.
- If you need to specify a regional variant, append a hyphen and the ISO 3166-1 region code (e.g., pt-BR for Brazilian Portuguese).
- Replace the invalid value in the lang attribute.
Some commonly used valid language codes:
| Language | Code |
|---|---|
| English | en |
| English (US) | en-US |
| English (UK) | en-GB |
| Spanish | es |
| French | fr |
| German | de |
| Portuguese (Brazil) | pt-BR |
| Chinese (Simplified) | zh-Hans |
| Japanese | ja |
| Arabic | ar |
Examples
❌ Invalid: Typo in language code
<html lang="emg">
❌ Invalid: Country code used instead of language code
<html lang="us">
❌ Invalid: Incorrect region subtag
<html lang="en-UK">
❌ Invalid: Made-up language code
<html lang="english">
✅ Valid: Correct two-letter language code
<html lang="en">
✅ Valid: Language with region subtag
<html lang="en-GB">
✅ Valid: Full document with proper lang attribute
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Ma page</title>
</head>
<body>
<p>Bonjour le monde !</p>
</body>
</html>
You can verify your language tag using the IANA Language Subtag Registry or the BCP 47 Language Subtag Lookup tool to ensure your code is valid before updating your markup.
The lang attribute on the <html> element sets the default language for all text content within the page. Without it, assistive technologies like screen readers have to guess which language the content is in, which can lead to garbled or incorrectly pronounced text. For example, a French screen reader attempting to read English text — or vice versa — produces a poor experience for users who rely on these tools.
Beyond accessibility, the lang attribute matters for several other reasons:
- Search engines use it to serve the correct language version of your page in search results.
- Browsers rely on it to choose appropriate fonts, hyphenation rules, and quotation mark styles.
- Translation tools use it to detect the source language of the page.
- CSS selectors like :lang() depend on it to apply language-specific styling.
The value of the lang attribute must be a valid BCP 47 language tag. Common examples include en (English), fr (French), es (Spanish), de (German), zh (Chinese), ja (Japanese), and ar (Arabic). You can also be more specific with region subtags, such as en-US for American English or pt-BR for Brazilian Portuguese.
If your page contains sections in a different language than the primary one, you can use the lang attribute on individual elements to override the document-level language for that section.
Examples
Missing lang attribute (triggers the warning)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My Page</title>
</head>
<body>
<p>Hello, world!</p>
</body>
</html>
Fixed with lang attribute
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Page</title>
</head>
<body>
<p>Hello, world!</p>
</body>
</html>
Using a region subtag for specificity
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="utf-8">
<title>My Page</title>
</head>
<body>
<p>Colour is spelt differently here.</p>
</body>
</html>
Overriding the language for a specific section
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Multilingual Page</title>
</head>
<body>
<p>This paragraph is in English.</p>
<p lang="fr">Ce paragraphe est en français.</p>
</body>
</html>
In this last example, the document language is English, but the second paragraph is marked as French. A screen reader will switch to French pronunciation rules for that paragraph, then revert to English for the rest of the page.
The < and > characters have special meaning in HTML — they signal the start and end of tags. When the parser encounters </>, it sees what looks like a closing tag with no element name, which is invalid in HTML. This sequence can appear in your markup for two main reasons:
- Unescaped text content: You’re trying to display the literal characters </> as visible text on the page (common in tutorials, documentation, or code snippets), but the browser interprets them as markup rather than content.
- Mistyped end tag: You intended to write a proper closing tag like </p> or </div> but accidentally omitted the element name, leaving just </>.
This matters because browsers may silently discard the malformed tag or interpret it in unexpected ways, leading to broken layouts or missing content. Screen readers and other assistive technologies may also struggle with the resulting DOM structure. Properly escaping special characters and writing well-formed tags ensures consistent rendering across all browsers and devices.
To fix this, determine which scenario applies. If you want to display the literal text </>, replace < with < and > with >. If you meant to close an element, add the correct element name between </ and >.
Examples
Unescaped angle brackets in text content
This triggers the error because the parser sees </> as an invalid closing tag:
<!-- ❌ Bad: raw </> in text content -->
<p>In JSX, self-closing tags use the </> syntax.</p>
Escape the angle brackets using HTML character entities:
<!-- ✅ Good: properly escaped characters -->
<p>In JSX, self-closing tags use the </> syntax.</p>
Mistyped closing tag with missing element name
This triggers the error because the closing tag has no name:
<!-- ❌ Bad: empty closing tag -->
<div class="container">
<p>Some content here.</p>
</>
Add the correct element name to the closing tag:
<!-- ✅ Good: proper closing tag -->
<div class="container">
<p>Some content here.</p>
</div>
Displaying code snippets with angle brackets
When writing about HTML or XML in your page content, all angle brackets in text must be escaped:
<!-- ❌ Bad: unescaped tags in text -->
<p>Use <strong> to make text bold and </strong> to close it.</p>
<!-- ✅ Good: escaped tags in text -->
<p>Use <strong> to make text bold and </strong> to close it.</p>
Using the <code> element for inline code
Even inside <code> elements, angle brackets must still be escaped — the <code> element only changes visual presentation, it does not prevent HTML parsing:
<!-- ❌ Bad: unescaped inside <code> -->
<p>A React fragment looks like <code><></code> and <code></></code>.</p>
<!-- ✅ Good: escaped inside <code> -->
<p>A React fragment looks like <code><></code> and <code></></code>.</p>
Using <pre> blocks for larger code examples
The same escaping rules apply within <pre> elements:
<!-- ✅ Good: escaped characters inside pre -->
<pre><code><div>
<p>Hello, world!</p>
</div></code></pre>
If you frequently need to display code and find manual escaping tedious, consider using a JavaScript-based syntax highlighting library that handles escaping automatically, or use a build tool or templating engine that escapes HTML entities for you.
The dir attribute specifies the base text direction for the content of an element. When a document is written in a right-to-left language like Arabic, Hebrew, Persian (Farsi), or Urdu, the browser needs to know that text should flow from right to left. Without this attribute, browsers default to left-to-right (ltr) rendering, which can cause a range of problems: text alignment may be incorrect, punctuation can appear in the wrong place, and the overall page layout may look broken or confusing to native readers.
This matters for several important reasons:
- Accessibility: Screen readers and other assistive technologies rely on the dir attribute to correctly announce and navigate content. Without it, the reading experience for users relying on these tools may be disorienting or incorrect.
- Visual correctness: Elements like lists, tables, form labels, and navigation menus will mirror their layout in RTL mode. Without dir="rtl", these elements default to LTR positioning, which feels unnatural for RTL language speakers.
- Bidirectional text handling: Documents often contain mixed-direction content (e.g., Arabic text with embedded English words, numbers, or brand names). The Unicode Bidirectional Algorithm (BiDi) uses the base direction set by dir to correctly resolve the ordering of these mixed runs of text.
- Standards compliance: The WHATWG HTML Living Standard recommends that authors set the dir attribute to match the language of the document, and the W3C Internationalization guidelines strongly encourage it for RTL languages.
How to fix it
Add dir="rtl" to your <html> start tag. If you haven’t already, also include the appropriate lang attribute for the specific language you’re using.
For Arabic:
<html dir="rtl" lang="ar">
For Hebrew:
<html dir="rtl" lang="he">
For Persian:
<html dir="rtl" lang="fa">
Examples
❌ Missing dir attribute on an Arabic document
<!DOCTYPE html>
<html lang="ar">
<head>
<meta charset="utf-8">
<title>مرحبا بالعالم</title>
</head>
<body>
<h1>مرحبا بالعالم</h1>
<p>هذه صفحة تجريبية باللغة العربية.</p>
</body>
</html>
The browser will render this page with a left-to-right base direction. The heading and paragraph text may appear left-aligned, and any mixed-direction content (like embedded numbers or English words) may be ordered incorrectly.
✅ Correct: dir="rtl" added to the <html> tag
<!DOCTYPE html>
<html dir="rtl" lang="ar">
<head>
<meta charset="utf-8">
<title>مرحبا بالعالم</title>
</head>
<body>
<h1>مرحبا بالعالم</h1>
<p>هذه صفحة تجريبية باللغة العربية.</p>
</body>
</html>
Now the browser knows to render the page right-to-left. Text will be right-aligned by default, scroll bars will appear on the left, and the overall layout will feel natural for Arabic readers.
Handling mixed-direction content within a page
If your RTL document contains sections in a left-to-right language, use the dir attribute on individual elements to override the base direction locally:
<p>قام المستخدم بزيارة <span dir="ltr">www.example.com</span> اليوم.</p>
This ensures the URL renders in the correct left-to-right order while the surrounding Arabic text flows right-to-left. Setting dir="rtl" on the <html> element establishes the correct default, and you only need per-element overrides for embedded LTR content.
The lang attribute on the <html> element declares the primary language of the document’s content. When this attribute is left empty (lang=""), it effectively tells browsers and assistive technologies that the language is unknown or intentionally unspecified — which is almost never what you want.
This matters for several important reasons:
- Accessibility: Screen readers rely on the lang attribute to select the correct pronunciation engine. An empty value can cause a screen reader to fall back to a default language, potentially reading English text with incorrect pronunciation rules.
- Search engines: Search engines use the lang attribute to understand what language your content is in, which helps serve your pages to the right audience.
- Browser features: Browsers use the language declaration for hyphenation, spell-checking, font selection, and other language-sensitive rendering decisions.
- Standards compliance: The WHATWG HTML living standard specifies that if the lang attribute is present, its value must be a valid BCP 47 language tag. An empty string is not a valid language tag.
The fix is straightforward: set the lang attribute to a valid BCP 47 language tag that matches your content. For English, common values include en (general English), en-US (American English), or en-GB (British English). If your content is in another language, use the appropriate tag (e.g., fr for French, de for German, ja for Japanese).
Examples
❌ Empty lang attribute (triggers the warning)
<!DOCTYPE html>
<html lang="">
<head>
<title>My Page</title>
</head>
<body>
<h1>Welcome to my website</h1>
</body>
</html>
❌ Missing lang attribute entirely
While a missing lang attribute triggers a different warning, it causes the same underlying problem — no language is declared:
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
</head>
<body>
<h1>Welcome to my website</h1>
</body>
</html>
✅ Correct: specifying the language
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<h1>Welcome to my website</h1>
</body>
</html>
✅ Correct: using a regional variant
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>My Page</title>
</head>
<body>
<h1>Welcome to my website</h1>
</body>
</html>
Using lang for mixed-language content
If your document is primarily in English but contains sections in other languages, set lang="en" on the <html> element and override it on specific elements:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Multilingual Page</title>
</head>
<body>
<h1>Welcome</h1>
<p>This page contains a quote in French:</p>
<blockquote lang="fr">
<p>La vie est belle.</p>
</blockquote>
</body>
</html>
The lang attribute on the <html> element declares the primary language of the document. The W3C validator uses heuristics to analyze the text content of your page, and when it detects a mismatch between the declared language and the apparent language, it raises this warning. For example, if your page content is written in English but lang="fr" (French) is set, the validator will flag this inconsistency.
Why This Matters
The lang attribute plays a critical role in several areas:
- Accessibility: Screen readers use the lang attribute to select the correct pronunciation rules and voice profile. If a page is written in English but declares French, a screen reader may attempt to read the content with French pronunciation, making it unintelligible to the user.
- Search engines: Search engines use the lang attribute to understand what language a page is in, which affects how the page is indexed and served in search results for different regions.
- Browser features: Browsers rely on the lang attribute for built-in translation prompts, spell-checking, hyphenation, and font selection. An incorrect value can cause unexpected behavior in all of these areas.
How to Fix It
- Identify the primary language of your content. Look at the actual text on your page — what language is the majority of it written in?
- Update the lang attribute to the correct BCP 47 language tag for that language (e.g., en for English, fr for French, es for Spanish).
- If the lang attribute is already correct and the validator’s heuristic is wrong (e.g., your page genuinely is in another language but contains some English text or code), you can safely ignore this warning.
For pages with mixed-language content, set the lang attribute on <html> to the primary language, then use lang attributes on specific elements to mark sections in other languages.
Examples
❌ Incorrect: Content is in English but lang declares French
<!DOCTYPE html>
<html lang="fr">
<head>
<title>My Website</title>
</head>
<body>
<h1>Welcome to my website</h1>
<p>This is an English paragraph about web development.</p>
</body>
</html>
The validator detects that the content is English, but lang="fr" says it’s French.
✅ Fixed: lang attribute matches the content language
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Website</title>
</head>
<body>
<h1>Welcome to my website</h1>
<p>This is an English paragraph about web development.</p>
</body>
</html>
✅ Mixed-language content with proper lang attributes
If your page is primarily in English but contains sections in another language, set the document language to en and annotate the foreign-language sections individually:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Language Examples</title>
</head>
<body>
<h1>Welcome</h1>
<p>This page is mostly in English.</p>
<blockquote lang="fr">
<p>Ceci est une citation en français.</p>
</blockquote>
</body>
</html>
This approach ensures screen readers switch pronunciation only for the French <blockquote>, while the rest of the page is correctly read as English.
The lang attribute on the <html> element tells browsers, search engines, and assistive technologies what language the page content is written in. The validator uses heuristic analysis of the actual text on the page to detect the likely language, and when there’s a mismatch, it flags the discrepancy.
Why This Matters
An incorrect lang attribute causes real problems for users and systems that rely on it:
- Screen readers use the lang attribute to select the correct pronunciation engine. A French document marked as English will be read aloud with English pronunciation rules, making it incomprehensible.
- Search engines use the language declaration for indexing and serving results to users searching in a specific language.
- Browser features like automatic translation prompts and spell-checking rely on the declared language.
- Hyphenation and typographic rules in CSS also depend on the correct language being declared.
Common Causes
- Copy-pasting a boilerplate — Starting from an English template but writing content in another language without updating lang.
- Multilingual sites — Using the same base template for all language versions without dynamically setting the lang value.
- Incorrect language subtag — Using the wrong BCP 47 language tag (e.g., lang="en" instead of lang="de" for German content).
When You Can Safely Ignore This Warning
This is a warning, not an error. The validator’s language detection is heuristic and not always accurate. You may safely ignore it if:
- Your page contains very little text, making detection unreliable.
- The page has significant amounts of content in multiple languages, but the lang attribute correctly reflects the primary language.
- The detected language is simply wrong (e.g., short text snippets can confuse the detector).
If you’re confident the lang attribute is correct, you can disregard the warning.
How to Fix It
Identify the primary language of your document’s content and set the lang attribute to the appropriate BCP 47 language tag. Common tags include en (English), fr (French), de (German), es (Spanish), pt (Portuguese), ja (Japanese), and zh (Chinese).
Examples
Incorrect: Content in French, but lang set to English
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Mon site</title>
</head>
<body>
<h1>Bienvenue sur notre site</h1>
<p>Nous sommes ravis de vous accueillir sur notre plateforme.</p>
</body>
</html>
This triggers the warning because the validator detects French content but sees lang="en".
Fixed: lang attribute matches the content language
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Mon site</title>
</head>
<body>
<h1>Bienvenue sur notre site</h1>
<p>Nous sommes ravis de vous accueillir sur notre plateforme.</p>
</body>
</html>
Handling mixed-language content
If your page is primarily in one language but contains sections in another, set the lang attribute on the <html> element to the primary language and use lang on specific elements for the other language:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Our Global Site</title>
</head>
<body>
<h1>Welcome to our site</h1>
<p>We are glad you are here.</p>
<blockquote lang="fr">
<p>La vie est belle.</p>
</blockquote>
</body>
</html>
This tells assistive technologies that the page is in English, but the blockquote should be read using French pronunciation rules. The validator should not flag this as a mismatch because the majority of the content is in English.
The lang attribute on the <html> element declares the primary language of the document’s content. When this attribute is missing or set incorrectly, the validator analyzes the text content and attempts to detect the language automatically. If it identifies a likely language, it produces this warning suggesting you add the appropriate lang value.
This matters for several important reasons:
- Accessibility: Screen readers rely on the lang attribute to select the correct pronunciation rules and voice profile. Without it, a screen reader might attempt to read Spanish text using English phonetics, producing unintelligible speech for the user.
- Browser behavior: Browsers use the language declaration for hyphenation, quotation mark styling, spell-checking, and font selection. For example, the CSS hyphens: auto property depends on the lang attribute to apply language-appropriate hyphenation rules.
- Search engines: Search engines use the lang attribute as a signal to understand the language of your content, which helps serve it to the right audience in search results.
- Translation tools: Automatic translation services use the declared language to determine whether (and from which language) to offer translation.
The value of the lang attribute must be a valid BCP 47 language tag. Common examples include en (English), es (Spanish), fr (French), de (German), zh (Chinese), ja (Japanese), and ar (Arabic). You can also specify regional variants like en-US, en-GB, pt-BR, or es-MX.
Examples
Missing lang attribute
This triggers the warning because the validator detects the content language but finds no lang declaration:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Mi Sitio Web</title>
</head>
<body>
<h1>Bienvenido a mi sitio web</h1>
<p>Este es un párrafo en español.</p>
</body>
</html>
Fixed with the correct lang attribute
Adding lang="es" tells browsers, screen readers, and search engines that this document is in Spanish:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Mi Sitio Web</title>
</head>
<body>
<h1>Bienvenido a mi sitio web</h1>
<p>Este es un párrafo en español.</p>
</body>
</html>
Mismatched lang attribute
This can also trigger the warning when the lang value doesn’t match the actual content. Here, the content is in French but the language is declared as English:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Mon Site Web</title>
</head>
<body>
<h1>Bienvenue sur mon site web</h1>
<p>Ceci est un paragraphe en français.</p>
</body>
</html>
The fix is to correct the lang value to match the content:
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Mon Site Web</title>
</head>
<body>
<h1>Bienvenue sur mon site web</h1>
<p>Ceci est un paragraphe en français.</p>
</body>
</html>
Using a regional variant
If you need to specify a regional variation, append the region subtag. For example, es-MX for Mexican Spanish or pt-BR for Brazilian Portuguese:
<!DOCTYPE html>
<html lang="es-MX">
<head>
<meta charset="UTF-8">
<title>Mi Sitio Web</title>
</head>
<body>
<h1>Bienvenido a mi sitio web</h1>
<p>Este es un párrafo en español de México.</p>
</body>
</html>
Sections in a different language
When your document is primarily in one language but contains sections in another, set the main language on <html> and use lang on individual elements for the exceptions:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Website</title>
</head>
<body>
<h1>Welcome to my website</h1>
<p>This site is available in multiple languages.</p>
<blockquote lang="es">
<p>Bienvenido a mi sitio web.</p>
</blockquote>
</body>
</html>
This approach ensures that assistive technologies switch pronunciation rules appropriately when they encounter the foreign-language section, while browsers and search engines still understand the primary document language.
In older HTML practices, developers sometimes used <meta http-equiv="Content-Language" content="en"> inside the <head> to declare the document’s primary language. The HTML living standard now marks this as obsolete because it was an unreliable and indirect way to communicate language information. It attempted to mirror an HTTP header rather than being a true part of the document structure, and its behavior was inconsistently implemented across browsers.
The lang attribute on the <html> element is the correct modern approach. It directly associates the language with the document’s DOM tree, which has several important benefits:
- Accessibility: Screen readers rely on the lang attribute to select the correct pronunciation rules and voice profile. Without it, assistive technology may mispronounce content or fall back to a default language that doesn’t match the text.
- Browser behavior: Browsers use the lang attribute to make decisions about hyphenation, font selection, quotation mark styling, spell-checking, and other language-sensitive rendering.
- Search engines: Declaring the language helps search engines index and serve content to the appropriate audience.
- CSS targeting: The :lang() pseudo-class selector works based on the lang attribute, enabling language-specific styling.
The lang attribute also supports granular, element-level language declarations. If your page is primarily in English but contains a French quote, you can set lang="fr" on that specific element — something the <meta> approach could never do.
Examples
Incorrect: using the obsolete meta tag
This triggers the W3C validation warning because <meta http-equiv="Content-Language"> is obsolete for specifying the document language.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Language" content="en">
<title>My Page</title>
</head>
<body>
<p>Hello, world!</p>
</body>
</html>
Correct: using the lang attribute on <html>
Remove the <meta http-equiv="Content-Language"> tag and add the lang attribute to the <html> element instead.
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p>Hello, world!</p>
</body>
</html>
Correct: mixed-language content
Use the lang attribute on the root element for the primary language, then override it on specific elements as needed.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Multilingual Page</title>
</head>
<body>
<p>The French word for hello is <span lang="fr">bonjour</span>.</p>
<blockquote lang="de">
<p>Die Grenzen meiner Sprache bedeuten die Grenzen meiner Welt.</p>
</blockquote>
</body>
</html>
Common language codes
Use a valid BCP 47 language tag as the value of the lang attribute. Here are some frequently used codes:
| Code | Language |
|---|---|
| en | English |
| fr | French |
| de | German |
| es | Spanish |
| pt-BR | Brazilian Portuguese |
| zh-Hans | Simplified Chinese |
| ja | Japanese |
The fix is straightforward: remove any <meta http-equiv="Content-Language"> tags from your <head> and ensure your <html> element includes a lang attribute with the appropriate language code. This single change resolves the validation warning while improving your document’s accessibility, rendering, and standards compliance.
The xml:lang attribute is a holdover from XHTML, where it was the standard way to declare the language of an element. In HTML5 (the text/html serialization), the lang attribute is the proper way to specify language. The HTML specification allows xml:lang for compatibility purposes, but only if it is accompanied by a lang attribute with an identical value. If xml:lang appears alone, or if its value doesn’t match the lang attribute, the document is non-conforming.
This matters for several reasons. Screen readers and other assistive technologies rely on the lang attribute—not xml:lang—to determine pronunciation and language-specific behavior. Search engines also use lang for content indexing and language detection. Having xml:lang without lang means the language declaration may be ignored entirely, degrading both accessibility and SEO.
In modern HTML5 documents, there is rarely a reason to include xml:lang at all. The lang attribute alone covers all use cases. The only scenario where you might need both is if your document must be compatible with both HTML and XHTML parsers (polyglot markup), in which case the two attributes must carry the same value.
How to Fix
You have two options:
- Remove xml:lang and use only lang (recommended for HTML5 documents).
- Add a lang attribute that matches the existing xml:lang value (for polyglot documents).
If you do keep both attributes, make sure the values are exactly the same—including case and subtags. For example, lang="en-US" must be paired with xml:lang="en-US", not xml:lang="en".
Examples
Incorrect: xml:lang without lang
<html xml:lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p xml:lang="fr">Bonjour le monde</p>
</body>
</html>
This triggers the validation error because both the <html> and <p> elements have xml:lang but no lang attribute.
Incorrect: Mismatched values
<html lang="en" xml:lang="en-US">
<head>
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
</body>
</html>
Even though both attributes are present, the values "en" and "en-US" don’t match, which is also invalid.
Correct: Using only lang (recommended)
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p lang="fr">Bonjour le monde</p>
</body>
</html>
This is the cleanest approach for HTML5 documents. The lang attribute is all you need.
Correct: Both attributes with matching values (polyglot)
<!DOCTYPE html>
<html lang="en" xml:lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p lang="fr" xml:lang="fr">Bonjour le monde</p>
</body>
</html>
If you must keep xml:lang, every element that has it must also have lang with the exact same value.
Ready to validate your sites?
Start your free trial today.