Standards Mode, Quirks Mode, and Doctype Sniffing
Some of the early browser implementations of CSS were fraught with problems—they only supported parts of the specification, and in some cases, the implementation of certain CSS features didn’t comply with the specification.
Today’s browsers generally provide excellent support for the latest CSS specification, even incorporating features that aren’t yet in the official specification, but will likely appear in the next version.
Due to the implementation deficiencies in early browsers, many old style sheets were written to work with the then-contemporary browsers rather than to comply with the CSS specification. This presented a dilemma for browser vendors releasing new versions of their products that had better support for the CSS standard. While they wanted to do the right thing with properly written CSS, and display web pages according to CSS standards, this had the potential to make a mess of millions of existing web pages whose CSS didn’t comply with the CSS specification.
The solution was to have the browser make an educated guess as to whether the current document seemed to be modern or old-school, and then choose the appropriate rendering mode. The basis for this guesswork was the presence, or absence, of an SGML document type declaration (or doctype declaration) in the markup. A doctype declaration contains the name of the document’s root element, and usually, a reference to the document type definition (DTD), which contains the syntactic rules for the markup language used in the document. Web browsers had so far ignored the doctype declaration, which was mainly intended for markup validators.
The process by which a browser chooses a rendering mode based on the doctype declaration is known as doctype sniffing (or doctype switching), and was first implemented in Microsoft Internet Explorer 5 for Mac OS. Today, doctype sniffing is also used in Opera (7 and later), Firefox and other Gecko-based browsers, Safari, Internet Explorer 6 and 7, and Konqueror (3.2 and later).
If the browser decides that the document is modern, it’ll render it in standards mode. This means that, as a rule, CSS is applied in accordance with the CSS2 specification.
If the browser decides that the document is old-school, it’ll render it in quirks mode. This mode applies CSS in the quirky way that suited predecessors of that browser, or even of other browsers. The exact implementations of quirks mode differ between browsers.
Opera (7.5 and later), Firefox, and Safari also have a third mode, called almost standards mode, in which the layout of images in table cells is implemented as in quirks mode, rather than in accordance with the CSS2 specification. In every other respect, this mode is equivalent to standards mode. Almost standards mode was added so that the old-school method of aligning images split across table cells is more likely to render as the authors intended, and not to fall apart. This mode corresponds to standards mode in Internet Explorer 6 and 7, Internet Explorer 5 for Mac OS and OS X, Konqueror, and Opera versions prior to 7.5. These browsers do not implement vertical alignment in table cells in compliance with the CSS2 specification, so their standards mode is really an almost standards mode.
Doctype sniffing is only undertaken for documents served with a MIME type of text/html. The specification of any XML MIME type, including application/xhtml+xml, automatically triggers standards mode (see MIME Types for more details).
How Does it Work?
So how does doctype
sniffing work? Which declarations trigger standards mode, quirks mode, and
almost standards mode? The document type definition reference, for HTML
and XHTML, consists of the string
PUBLIC followed by a
formal public identifier (FPI), optionally followed
by a formal system identifier (FSI), which is the
URL for the DTD.
Here’s an example of a doctype declaration that contains both an FPI and an FSI:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
This example contains only the FPI:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
Doctype sniffing works by detecting which of these parts are present in the doctype declaration. If an FPI is present, but an FSI isn’t, browsers generally choose quirks mode, since this was the common way of writing doctype declarations in the old days. Browsers also choose quirks mode if the doctype declaration is missing altogether—which used to be very common—or is malformed.
If both an FPI and a correct FSI are present, browsers with two layout modes choose their standards mode. Browsers with three layout modes will examine the DTD reference before committing to a choice. Generally, the DTDs for HTML 4.0 Strict, HTML 4.01 Strict, and XHTML 1.0 Strict trigger standards mode. The corresponding Transitional DTDs trigger almost standards mode for a text/html MIME type.
Internet Explorer 6 uses a very primitive form of doctype sniffing, which presumes that the doctype declaration is the very first line in the document. An SGML comment before the doctype declaration will trigger quirks mode, as will an XML declaration before an XHTML doctype—even XHTML 1.0 Strict. The following declaration will trigger quirks mode in IE6 (but not IE7) if served as text/html:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
For more detailed information about doctype sniffing, including a table of which doctypes trigger specific rendering modes in different browsers, see http://hsivonen.iki.fi/doctype/.