Why does my HTML pass in the browser but fail validation?
Because browsers are required to repair broken markup rather than reject it. The page renders, and the DOM you get is not the one you wrote.
By Sapun Lamichhane · Arcetis
Because browsers are required to repair broken markup rather than reject it. The HTML specification defines exactly how to recover from every parse error, so a document with mis-nested tags renders perfectly - and the DOM your CSS and JavaScript run against is not the DOM you wrote.
That gap is the entire reason to validate. The page looks right, so nothing prompts you to check, and the difference only surfaces later as a selector that matches nothing or a component that renders in the wrong place.
What does the browser actually change?
Four repairs account for most of it, and none of them is visible without looking:
- Nested anchors are split. `<a href="/a">one <a href="/b">two</a></a>` becomes two sibling links, so a selector expecting one link finds two.
- An unclosed paragraph is closed for you. `<p>text<div>block</div>` becomes `<p>text</p><div>block</div>` - the div is now a sibling, not a child, and `p > div` matches nothing.
- A bare `<tr>` gets a `<tbody>` injected around it. CSS written as `table > tr` stops matching, because there is now a tbody in between.
- A nested form is discarded entirely. The inner form's fields remain in the DOM and belong to the outer form, so they submit to the wrong endpoint or not at all.
Why does my validator say the page is fine?
Almost certainly because it is reading the rendered DOM. Any tool that inspects a page through a browser - or through a headless browser's serialised output - is inspecting the repaired version. The errors were removed before the tool arrived.
A validator has to read the raw response body, before JavaScript runs and before the parser has restructured anything. That is what the W3C's Nu Html Checker does, and it is why its results sometimes disagree with a devtools-based tool that claims to check the same thing.
Which errors are worth fixing first?
Rank them by whether they change the DOM shape. Errors that do are the ones that break things:
- 1Nesting and closing errors - these move elements, which breaks CSS, JavaScript and the accessibility tree.
- 2Duplicate ids - `getElementById` returns the first match forever, and `aria-labelledby` and `label[for]` silently bind to the wrong element.
- 3Missing required attributes - an `<img>` without `src`, a `<link>` without `rel`. The element exists and does nothing.
- 4Obsolete elements and attributes - `<center>`, `<font>`, `align`. These still render but are removed from the standard and unsupported in future engines.
Formatting complaints - attribute quote style, tag case, trailing whitespace - are linter opinions, not defects. A validator that mixes them into the same list makes the real problems harder to find.
How do I check my own page?
Run it through the HTML validator on this site: it reads the pre-JavaScript response body, checks it against the HTML Living Standard's content model with a real tokenizer, and reports the line and column of each error. Accessibility rules are deliberately kept separate, in the accessibility checker, so the same missing alt attribute is never counted twice.