HTML Validator & Linter
Validates HTML documents for well-formedness and best practices: finds missing or unbalanced tags, unknown elements, duplicate IDs, missing required attributes, obsolete markup and more.
Result
What the HTML validator checks
The validator tokenizes your document exactly like a browser does (comments, doctype, raw-text elements such as <script> and <style>, quoted and unquoted attributes, self-closing syntax) and then rebuilds the element tree, applying the HTML5 rules for void elements and optional end tags. Everything runs in your browser; nothing is uploaded. Issues are reported with their line and column and grouped in three levels:
| Level | What it means |
|---|---|
| error | The markup is invalid HTML5: browsers will recover, but usually not the way you intended (elements silently closed or moved, text swallowed, duplicated ids breaking scripts and labels). |
| warning | Valid but discouraged: obsolete elements and attributes, missing metadata, accessibility problems that affect real users. |
| info | Style and best-practice hints: inline styles and handlers, upper-case tags, heading structure, viewport. |
Structural errors
- Unknown elements — every HTML5 element is accepted, including
main,section,article,details,dialog,template,slot,picture,video,canvas,svgandmath. Custom elements are accepted when their name contains a hyphen (<my-widget>). Inside<svg>and<math>any tag name is allowed. Anything else (<div2>,<spam>,<layer>) is reported. - Unclosed and mismatched tags — each end tag must match the innermost open element, taking into account void elements (
area base br col embed hr img input link meta param source track wbr, which never have an end tag) and elements whose end tag is optional (p li dt dd tr td th thead tbody tfoot option optgroup html head body colgroup caption rp rt). An end tag with nothing to close is a stray end tag. - Content model —
<p>may only contain phrasing content: a block element such asdiv,ulortableinside a paragraph implicitly closes it.<li>must be a child oful/ol/menu;<tr>of a table section;<td>/<th>oftr;<option>ofselect/datalist/optgroup. Links cannot be nested in links, forms in forms, buttons in buttons. Onlytitle,meta,link,style,script,baseandnoscriptbelong in<head>. - Attributes — duplicate attributes, duplicate
idvalues, ids containing whitespace, unquoted values that contain quotes,=,<or backticks, unterminated quotes, missing whitespace between attributes. - Doctype and syntax — a missing doctype (which triggers quirks mode), an obsolete doctype (only
<!DOCTYPE html>is current), an unescaped<in text,<!that is not a comment, CDATA sections outside SVG/MathML, XML processing instructions, unterminated comments and--inside comments.
Best-practice warnings
- Missing
<title>, missing<meta charset="utf-8">, missinglangattribute on<html>, more than one<main>. - Obsolete elements:
font center marquee blink applet frame frameset big tt strike acronym dir basefont isindex nobr— with the modern replacement. - Obsolete presentational attributes:
bgcolor,align,valign,border(exceptborder="1"on tables),cellpadding,cellspacing,width/heighton elements other than images, media and frames,languageon<script>,nameon<a>,typeon lists… - Unquoted attribute values, self-closing syntax on non-void elements (
<div/>does not close the div), emptyhref/src, unescaped&that does not start a character reference, entities without a semicolon. - Info: inline event handlers (
onclick…), inlinestyleattributes, upper-case tag names, unnecessarytype="text/javascript", several<h1>, skipped heading levels.
Accessibility hints
<img>withoutalt(usealt=""for purely decorative images),<input type="image">and<area>withoutalt.- Form controls without an associated
<label>(wrapping,for="id",aria-labeloraria-labelledby). - Links and buttons with no accessible name (no text, no image with alt, no
aria-label). - Data tables without
<th>or<caption>, iframes withouttitle,<a href="#">used as a button, missing viewport meta tag.
Common mistakes
| Wrong | Right | Why |
|---|---|---|
<p>Text<div>…</div></p> | <div><p>Text</p>…</div> | A block element closes the paragraph; the final </p> becomes an empty paragraph. |
<br/></br>, </img> | <br>, <img …> | Void elements never have an end tag. |
<a href="x"><a href="y">… | Separate links | Links cannot be nested. |
<ul><div><li>… | <ul><li><div>… | Only li may be a child of a list. |
<div id="x">…<div id="x"> | Unique ids, classes for repetition | Duplicate ids break getElementById, labels and anchors. |
<a href="?a=1&b=2"> | <a href="?a=1&b=2"> | &b may be interpreted as a character reference. |
<div class=my box> | <div class="my box"> | Unquoted values stop at the first space. |
<font color="red"> | <span class="alert"> + CSS | Presentation belongs to CSS. |
<img src="a.png"> | <img src="a.png" alt="Chart of sales"> | Screen readers and broken images need the text. |
A minimal valid HTML5 document
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Page title</title>
</head>
<body>
<main>
<h1>Heading</h1>
<p>Paragraph with a <a href="https://example.com">link</a>.</p>
</main>
</body>
</html>
Note: this validator checks syntax, structure and a curated set of best practices. It does not validate every attribute value or the full HTML content model like the W3C Nu HTML checker does; use it as a fast first pass.