deadhead
document/doctype

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

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.