Missing or non-standard doctype
The page has no doctype, or one other than <!doctype html>; a missing or legacy doctype can put the browser in quirks or limited-quirks mode, where CSS layout follows old compatibility rules.
- Avoid
- Harmful
- Severity
- HarmfulActively breaks something for users.
- Basis
- SpecifiedThe evidence is in a current standard.
- Detectable
- YesMatched exactly. Autofixable when the rule carries a fix.
- Matches
logic moduleDocument rule, anywhere in the document.- Fix
- None — reports only
- Impacts
- Interoperability
- Related
head/charset-position,document/html-lang
The doctype is the first line of an HTML file, and in HTML it has exactly one form:
<!doctype html>. It declares no version and points at no DTD. Its only job left is to tell
the browser to render the page by today’s rules. Leave it out, or keep an old
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">, and many browsers switch to
a compatibility mode instead.
Why avoid
The HTML Standard is blunt about it: “A DOCTYPE is a required preamble. DOCTYPEs are required for
legacy reasons. When omitted, browsers tend to use a different rendering mode that is incompatible
with some specifications.” The only conforming form is <!DOCTYPE html>, in any letter case. A
generator that can’t produce that may add the legacy string, as in
<!DOCTYPE html SYSTEM "about:legacy-compat">, which the standard allows but discourages.
The parser uses the doctype to choose the rendering mode, and the rules are written into the standard:
- No doctype means quirks mode, always.
- Old public identifiers mean quirks mode. The list covers HTML 2.0 to 3.2, HTML 4.0, vendor DTDs, and HTML 4.01 Transitional or Frameset when the system identifier is missing.
- XHTML 1.0 Transitional or Frameset, and HTML 4.01 Transitional or Frameset with a system identifier, mean limited-quirks mode.
- Anything else that isn’t
<!DOCTYPE html>is still a parse error, but renders normally.
Quirks mode isn’t cosmetic. The Quirks Mode Standard lists what changes: percentage heights are
calculated differently, html and body stretch to fill the viewport, table cells size
themselves by old rules, tables stop inheriting color and text decoration, and CSS accepts
unitless lengths and hex colours without a #. MDN puts it plainly: “In quirks mode, layout
emulates behavior in Navigator 4 and Internet Explorer 5.” Limited-quirks mode keeps one of those
rules, the line height calculation quirk, which is where the classic gap under images in table
cells comes from.
The result is a page that renders by rules no modern stylesheet is written for. The same CSS
behaves differently on this page than on the rest of a site, and the cause is invisible unless
someone checks document.compatMode, which reads BackCompat in quirks mode.
Use instead
Make <!doctype html> the first line of every page:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>…</title>
</head>
<body>
</body>
</html>
Comments and whitespace may come before it, and so may a byte order mark. Text or any element may not: after those, the parser has already chosen quirks mode and ignores the doctype.
Detectability
Detectable in all three runtimes. The rule mirrors the parser’s own test: the doctype must be
named html, have no public identifier, and have either no system identifier or
about:legacy-compat. A missing doctype is reported on the <html> element. A doctype after text
or an element is reported as missing too, because the browser ignores it.
Every non-conforming doctype is reported, including the few, like HTML 4.01 Strict, that render in no-quirks mode. The finding’s detail names what is wrong rather than the rendering mode.
Some malformed doctypes aren’t caught: one that switches the parser to quirks mode while still
reading as a plain html doctype, such as <!DOCTYPE html bogus>, and an explicitly empty
identifier, such as PUBLIC "". There is no autofix, because changing a doctype changes the
rendering mode, which is the one thing a fix must never do.
Resources
- HTML Standard — The DOCTYPE — the doctype is required;
<!DOCTYPE html>is its only form, plus the discouraged legacy string. - HTML Standard — The “initial” insertion mode — which doctypes are parse errors, which set quirks or limited-quirks mode, and that a missing doctype sets quirks mode.
- Quirks Mode Standard — the CSS and layout differences in quirks and limited-quirks mode.
- MDN — Quirks mode and standards mode — the three modes, and
document.compatModeas the way to check.
This page is generated from content/rules/document/doctype.md, the same file the linter is built from. Think the rule is wrong, or that browsers moved on? Say so — that is the most useful issue you can file.