HTML Syntax Validator

A page looks right in Chrome, then the sidebar drops below the fold in Safari and the source gives nothing away. Paste the markup here and the unclosed div, the repeated id and the paragraph a browser closed early all come back with a line number.

HTML validation workspace

Check against
Depth

Markup

Waiting for markup

Paste markup on the left, open an .html file, or load one of the two samples.

Lines 0Size 0 BElements 0Deepest nesting 0Read as Nothing yetClick any finding to select the line it came from

Browsers repair broken markup in silence, and the repair is the bug

The HTML parser in every browser is built so it never fails. Leave out a closing div and it invents one somewhere. Put a div inside a paragraph and it ends the paragraph on the spot, then discards the real closing tag when it turns up eleven lines later. Nothing reaches the console. The page renders.

Two weeks pass. A layout collapses in one browser, a label reads out the wrong field name, or a script picks up the wrong element by id. You open the file, read it top to bottom, and it looks correct, because the mistake lives in the tree the parser built rather than the text you are looking at.

This page shows you the difference.

Markup goes on the left. The report rebuilds on the right a quarter of a second after you stop typing, and every finding carries a line, a column, the source line it came from and a note on what the browser does about it. Click a finding and the editor selects that line.

How the scan walks your document

The document is read character by character rather than through a pile of regular expressions. Tags, attributes, comments, the DOCTYPE and the raw contents of script, style, textarea and title are each handled on their own terms, so a < inside a script body never gets mistaken for a tag.

Open tags go on a stack. Closing tags pop it. Elements with optional end tags follow the same implicit rules a browser uses, so a list written as <li>One<li>Two passes without complaint, while a <div> opened inside a <p> reports the paragraph it silently ended. Anything left on the stack at the end of the file is reported as never closed, with the line where it opened.

Three depths decide how much runs, and the version buttons change the rules underneath all of them:

DepthWhat runsWhen to use it
Structure onlyDOCTYPE, html, head, body, title, tag pairing, unterminated commentsA first look at markup somebody else handed you
StandardAdds unknown elements, deprecated tags and presentation attributes, repeated ids, duplicate attributes, unquoted values, nesting rulesThe working default while you write a template
Standard and accessibilityAdds alt text, form labels, heading order, frame titles, the lang attribute, tab order, keyboard reachabilityBefore a page goes anywhere near production

A fragment with no DOCTYPE, no <html> and no <body> is read as a fragment, so the five whole-document findings stay quiet. Paste a partial from a template directory and you get tag and attribute findings without five lines of noise about a missing title.

Findings people do not expect

Most of what turns up is ordinary: a typo in a tag name, a closing tag that lost its partner during an edit. Three findings surprise people often enough to name here.

Load the broken landing page sample and read line 12. The paragraph opens, a div follows on line 13, and the report says the paragraph ended on line 13 rather than at the </p> on line 14. Line 14 then shows a second finding, a closing tag with nothing to close, because the browser already dealt with the paragraph. One mistake, two findings, and neither of them appears in any console.

Where this fits in a working day

Hand-written pages are a small part of it. Most markup pasted in here arrives from somewhere else.

When the W3C service is the better call

The Nu validator at validator.w3.org carries the full content model from the specification. It knows which elements are permitted inside which, checks attribute values against their allowed sets, and produces the answer you quote when a contract asks for conformance. Use it when being right about the spec is the point.

This page answers a narrower question, faster. It finds the mistakes that change what a browser builds, with no upload, no queue and no round trip, updating as you edit. In practice the two get used at different moments: this one while the markup is still moving, the W3C service once it stops.

Once the findings are clear, the HTML Beautifier handles indentation across a whole file, and the HTML Cleaner strips the leftovers a word processor leaves in pasted content. Stylesheets are a separate job with separate rules, so those go to the CSS Syntax Validator.

What this checker will not tell you

Nothing leaves the tab

The scanner, the indenter and the file picker all run in your browser. No request goes out once the page has loaded, so cut your connection and every button still works.

That matters more than it sounds for this particular tool. Markup pasted into a validator regularly carries customer names, order references, staging URLs and the odd API key sitting in a data attribute. None of it should leave your machine to find a missing div.

Questions that come up while fixing markup

Errors against warnings, template languages, and what a clean report is worth.

Why does the report say my paragraph closed before the closing tag I wrote?

Because a paragraph holds text and inline elements only. When a div, a table, a list or another paragraph opens inside it, the HTML parser closes the paragraph at that point. Your closing tag then arrives with nothing left to close, which produces a second finding on that line. Move the block element out of the paragraph, or change the paragraph to a div if it was wrapping layout rather than prose.

What separates an error from a warning here?

An error means the browser builds a different tree from the one your source describes: an unclosed tag, a stray closing tag, a repeated id, a link inside a link. A warning means the markup parses as written and something about it is worth changing, such as a deprecated element or a missing viewport tag. Accessibility findings are listed on their own because they rarely affect rendering and often affect whether the page is usable at all.

Does a clean accessibility column mean the page passes WCAG?

No. It means the problems visible in static markup are gone. Colour contrast, focus order during real use, reading order and anything depending on a rendered page cannot be judged from source text. Treat the strict depth as the first pass that clears the obvious failures, then test with a keyboard and a screen reader.

Will Blade, Twig or Handlebars markup work in here?

Template expressions are treated as ordinary text, so a page full of double braces checks fine. The exception is control flow that splits a tag pair across branches, where one branch opens a div and another closes it. The checker reads what is in front of it and reports the tags as mismatched. Paste rendered output instead when a template does that.

Why is a placeholder not accepted as a label?

A placeholder disappears the moment somebody types, which leaves the field with no visible name during the exact moment they need it. Several screen readers skip it, and voice control has nothing to target. Use a label element with a for attribute matching the field id. Where the design has no room for visible text, aria-label on the field also satisfies the check.

Which version should I select?

HTML5 unless the file says otherwise. Choose HTML 4.01 for an old page or an email template, and presentation attributes such as align and cellpadding stop being reported, since they were legal then. XHTML 1.0 adds the strict rules from that era: lowercase element names, quoted attribute values, no attribute minimisation and a closing slash on every void element.

Is my markup uploaded anywhere?

No. Parsing, formatting and the file picker run in the page itself, and no network request is made after the page loads. Switch off your connection and the tool keeps working, which is the point when the markup you are checking holds staging URLs or customer data.