HTML Guide
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.
This validation issue indicates that your HTML document does not specify a language for its content. Specifying the document’s language is important for accessibility, search engines, and browser behavior.
To fix this, you need to add the lang attribute to the <html> element, indicating the primary language of the document. For example, if your document is written in Spanish, you should set the lang attribute to "es".
Here’s how to do it:
Original HTML (without lang attribute)
<!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>
Updated HTML (with lang attribute)
<!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>
Explanation
- The lang="es" attribute specifies that the primary language of the document is Spanish.
- Setting the lang attribute helps screen readers and other assistive technologies to better interpret the content.
- It also provides crucial information for search engines and browsers, improving the accessibility and search engine optimization (SEO) of your website.
If you need to specify a regional variation of Spanish, you can use values like lang="es-ES" for Spanish as used in Spain, or lang="es-MX" for Spanish as used in Mexico.
Example with Regional Variation
<!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>
By adding the lang attribute with the appropriate value, you’ll resolve the W3C HTML Validator issue.
Void elements, like area, base, br, col, embed, hr, img, input, link, meta, source, track, and wbr are self-closing and don’t need a trailing slash /, which should be avoided as that can interfere with unquoted attribute values.
These void elements can optionally have a trailing slash and some people prefer to include it as it may look clearer. Some HTML formatters integrated in code editors automatically add a trailing slash to void elements.
So for example, both <hr> and <hr/> are valid self-closing void elements. However, when combined with unquoted values for attributes, the trailing slash can be problematic.
In this example, the img element takes http://example.com/logo.svg as the value its src attribute.
<img alt=SVG src=http://example.com/logo.svg>
But in the following example with a trailing slash, the img element takes http://example.com/logo.svg/ as the value its src attribute. That is, the trailing slash has been parsed as part of the value for the src attribute, which breaks the display of the image.
<img alt=SVG src=http://example.com/logo.svg/>
In short, this HTML warning makes you aware of this problem. When possible, it’s recommended to avoid trailing slashes in void elements.
A <span> tag has not been closed. Example:
<p><span>I'm forgetting something</p>
<p>Life goes on</p>
When the validator reports “Unclosed element ‘X’”, it means an opening tag like <div> or <p> was never terminated with its required closing tag </div> or </p>, or it was closed out of order. HTML parsing then tries to auto-close elements, which can reshape the DOM in ways you didn’t intend. This often happens with nested structures, copy‑paste edits, or when mixing void elements (which never have closing tags) with normal elements.
Leaving elements unclosed can break layout and styles, confuse assistive technologies that rely on a well-formed structure, and cause scripts or CSS selectors to behave unpredictably. It also harms portability between browsers and tools, and makes maintenance harder because the rendered tree differs from what the source suggests.
To fix it, ensure that:
- Every non-void element has a matching end tag: open <section>, close with </section>.
- Nesting is properly balanced: the last opened element is the first one you close (LIFO).
- You do not add closing tags to void elements like br, img, input, meta, link, or hr. These must not have end tags in HTML, and you don’t need a trailing slash.
- Self-closing syntax (<br />) is permitted but treated as <br> in HTML; do not rely on it to close non-void elements.
- Use your editor’s bracket/tag matching or formatter to spot mismatches, and validate early.
Examples
Example that triggers the issue (unclosed element)
<!-- Problem: <div> is never closed, and <p> is closed after a new <div> starts -->
<div class="card">
<h2>Title</h2>
<p>Some text
<div class="footer">
<p>Footer text</p>
</div>
Fixed: properly closed and correctly nested
<div class="card">
<h2>Title</h2>
<p>Some text</p>
<div class="footer">
<p>Footer text</p>
</div>
</div>
Example that triggers the issue (out-of-order closing)
<!-- Problem: <em> is opened inside <strong> but closed after </strong> -->
<p><strong><em>Important</strong></em> notice</p>
Fixed: close in reverse order of opening
<p><strong><em>Important</em></strong> notice</p>
Example that triggers the issue (incorrectly “closing” a void element)
<!-- Problem: void elements must not have end tags -->
<p>Line one</p>
<br></br>
<p>Line two</p>
Fixed: use void elements without end tags
<p>Line one</p>
<br>
<p>Line two</p>
Full document example with a common pitfall (lists and paragraphs)
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Unclosed Element Fix</title>
</head>
<body>
<!-- Problem avoided: do not nest <li> across paragraph boundaries -->
<ul>
<li>
<p>Item one title</p>
<p>Item one details</p>
</li>
<li>
<p>Item two</p>
</li>
</ul>
</body>
</html>
Tips to prevent “Unclosed element” errors
- Keep indentation consistent; it visually reflects nesting.
- Close tags immediately after opening, then fill content.
- Use linters/formatters (e.g., HTMLHint, Prettier) and run the W3C validator regularly.
- Be cautious when mixing templating logic; ensure conditionals don’t skip required end tags.
Specify the language of your HTML document using the lang attribute on the <html> element instead of using a <meta> tag for the language.
The HTML5 standard encourages specifying the primary language of a document using the lang attribute on the <html> element. The lang attribute should be set to a valid language code, such as en for English or fr for French. Using a <meta> tag to declare the document language is considered obsolete because the <meta> tag cannot convey element-specific language information. The lang attribute is more versatile and directly associates the language with the HTML document structure itself. This approach aligns better with accessibility requirements and helps user agents understand and render the content appropriately.
Here is how you should specify the language using the lang attribute:
Correct usage with lang attribute:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document with Language Specification</title>
</head>
<body>
<p>This document is written in English.</p>
</body>
</html>
Incorrect usage with <meta> tag:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Language" content="en">
<title>This usage is considered outdated</title>
</head>
<body>
<p>This should not be done in HTML5.</p>
</body>
</html>
By defining the language with the lang attribute directly in the <html> tag, you improve the document’s compliance with modern standards and enhance the accessibility and internationalization aspects of your web content.
Mismatch between the declared character encoding and the actual encoding confuses browsers and validators, and can cause character display issues.
The charset declaration in the meta tag should match the actual character encoding of your HTML file. Declaring "iso-8859-1" but saving the file as "windows-1252" (or vice versa) creates a conflict, since these encodings are similar but not identical. Moreover, UTF-8 is the recommended encoding for web documents, widely supported and preferable for modern websites.
To resolve the issue:
- Decide which character encoding your HTML file should use.
- Save your document with that encoding in your text editor or IDE.
- Ensure your HTML declares the same encoding using the meta tag in the <head> section.
Example using UTF-8 (recommended):
<!DOCTYPE html>
<html lang="en">
<head>
<title>Example</title>
<meta charset="utf-8">
</head>
<body>
<p>Hello, world!</p>
</body>
</html>
If you specifically want iso-8859-1:
- Save the file as iso-8859-1 in your editor.
-
Declare it in your HTML:
<!DOCTYPE html> <html lang="en"> <head> <title>ISO Example</title> <meta charset="iso-8859-1"> </head> <body> <p>Bonjour, monde !</p> </body> </html>
Make sure your editor does not save the file as windows-1252 if you declare iso-8859-1 in your HTML. For best compatibility, use UTF-8 for both saving and declaring the document encoding.
Elements that have the xml:lang attribute also need a matching lang attribute. In HTML5 documents, using just the lang attribute is enough.
A srcset attribute with width descriptors requires a sizes attribute on the img element.
When you use width descriptors (e.g., 400w, 800w) in the srcset attribute, the browser needs the sizes attribute to correctly select the appropriate image source based on the layout size in the viewport. Without sizes, the HTML is invalid, and the browser cannot resolve how large the image will be displayed.
Explanation
The srcset attribute allows you to provide multiple image sources for different screen conditions. There are two types of descriptors in srcset: width descriptors (e.g., 400w) and pixel density descriptors (e.g., 2x). When using width descriptors, you must include a sizes attribute to describe the expected display width of the image in CSS pixels. This helps browsers pick the best matching source.
Correct Usage Example
<img
src="image-400.jpg"
srcset="image-400.jpg 400w, image-800.jpg 800w"
sizes="(max-width: 600px) 100vw, 600px"
alt="Responsive example">
Incorrect Usage Example
<img
src="image-400.jpg"
srcset="image-400.jpg 400w, image-800.jpg 800w"
alt="Responsive example">
(Missing sizes attribute)
Explanation of the correct example:
- The srcset attribute lists two images with their respective pixel widths.
- The sizes attribute tells the browser to use 100vw (100% of the viewport width) if the viewport is 600px wide or less, and otherwise use 600px as the display width.
Attribute values for HTML elements must be enclosed within quotes. Check for attributes whose values are missing quotes.
Example:
<!-- These are invalid -->
<div class=important></div>
<div class=important"></div>
<!-- This is valid -->
<div class="important"></div>
The X-UA-Compatible meta tag or HTTP header value must be set to IE=edge instead of IE=10 for modern browser compatibility.
The X-UA-Compatible HTTP header or <meta http-equiv="X-UA-Compatible"> element instructs Internet Explorer which document mode to use. Setting it to IE=10 forces the page into IE10 rendering mode, which is outdated and may cause issues with modern web standards. The recommended value is IE=edge, which tells IE to use the highest supported mode available, ensuring the browser uses the latest standards.
Example of the correct <meta> tag for compliance:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Correct X-UA-Compatible Example</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
</head>
<body>
<!-- Page content -->
</body>
</html>
Remove any instance like IE=10 and replace with IE=edge to resolve the validator issue.
Setting the X-UA-Compatible HTTP header with the value IE=edge,chrome=1 is non-standard; it should be set to IE=edge only.
The X-UA-Compatible header is used to specify how Internet Explorer should render a webpage. It allows web developers to opt into the latest standards mode in IE, thus ensuring better compatibility and performance by avoiding compatibility modes that simulate older browser versions. Setting it to IE=edge tells IE to use the highest mode available, which is the most standards-compliant mode the browser supports. The additional ,chrome=1 directive was used for a Google Chrome Frame feature, which is now deprecated and should not be used in modern webpages.
To ensure your HTML document meets the W3C standards, you must remove ,chrome=1 and just have the IE=edge value. Here’s how you can properly set the X-UA-Compatible header:
- In HTML Meta Tags: Ensure your meta tag within the HTML document head is correctly written.
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>My Web Page</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
- In HTTP Headers: If you’re setting the X-UA-Compatible via server configuration, for example in an .htaccess file (for Apache), ensure it’s configured without the ,chrome=1.
# .htaccess example
<IfModule mod_headers.c>
Header set X-UA-Compatible "IE=edge"
</IfModule>
Correctly setting this ensures that your page is rendered with the most up-to-date rendering engine, enhancing compatibility and performance across modern web standards.