CINXE.COM
CSS - Quirks mode and strict mode
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang="en"> <head> <title>CSS - Quirks mode and strict mode</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <link rel="stylesheet" href="../quirksmode.css" /> <link rel="up" href="contents.html" /> <script type="text/javascript" src="../quirksmode.js"></script> </head> <body> <h2>Quirks mode and strict mode</h2> <div id="header"></div> <div class="floater"> <p>Further information can be found at <a href="http://www.cs.tut.fi/~jkorpela/quirks-mode.html" class="external">Jukka K. Korpela’s Quirks Mode features page</a>.</p> <p><a href="https://hsivonen.iki.fi/doctype/" class="external">Browser comparison</a>: which doctype triggers which mode?</p> <p>IE 5 Windows and Netscape 4: Doctype switching not possible; permanently locked in quirks mode.</p> <p>IE 6 Windows: <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnie60/html/cssenhancements.asp" class="external">CSS Enhancements in Internet IE 6</a></p> <p>IE 5 Mac: No official support page, but Eric Meyer has <a href="http://www.oreillynet.com/pub/a/network/2000/04/14/doctype/index.html" class="external">summarized</a> the differences.</p> <p>Mozilla: <a href="http://www.mozilla.org/docs/web-developer/quirks/doctypes.html" class="external">DOCTYPEs</a> and <a href="http://www.mozilla.org/docs/web-developer/quirks/quirklist.html" class="external">list of quirks</a>.</p> <p>Opera 7: <a href="http://www.opera.com/docs/specs/doctype/" class="external">The Opera 7 DOCTYPE Switches</a></p> <p>Safari: No official support page, but it largely follows Mozilla.</p> </div> <p class="intro">Quirks mode and strict mode are the two ’modes’ modern browsers can use to interpret your CSS. This page gives a short overview of the reasons for and the differences between these two modes.</p> <h3>The problem</h3> <p>When Netscape 4 and IE 4 implemented CSS, their support did not match the W3C standard (or, indeed, each other). Netscape 4 had horribly broken support. IE 4 came far closer to the standard, but didn’t implement it with complete correctness either. Although IE 5 Windows mended quite a lot of IE 4 bugs, it perpetuated other glitches in CSS (mainly the box model).</p> <p>To make sure that their websites rendered correctly in the various browsers, web developers had to implement CSS according to the wishes of these browsers. Thus, most websites used CSS in ways that didn’t quite match the specifications.</p> <p>Therefore, when standards compliancy became important browser vendors faced a tough choice. Moving closer to the W3C specifications was the way to go, but if they’d just change the CSS implementations to match the standards perfectly, many websites would break to a greater or lesser extent. Existing CSS would start to show odd side effects if it were suddenly interpreted in the correct way.</p> <p>So moving closer to standards compliance would cause problems. On the other hand, not moving closer to standards compliance would perpetuate the general confusion of the Browser Wars Era.</p> <h3>The solution</h3> <p>Therefore any solution to this problem had to</p> <ol> <li>allow web developers who knew their standards to choose which mode to use.</li> <li>continue displaying old pages according to the old (quirks) rules.</li> </ol> <p>In other words, all browsers needed two modes: quirks mode for the old rules, strict mode for the standard. IE Mac was the first browser to implement the two modes, and IE Windows 6, Mozilla, Safari, and Opera followed suit. IE 5 Windows, as well as older browsers like Netscape 4, are permanently locked in quirks mode.</p> <p>Choosing which mode to use requires a trigger, and this trigger was found in ’doctype switching’. According to the standards, any (X)HTML document should have a doctype which tells the world at large which flavour of (X)HTML the document is using.</p> <ul class="spacing"> <li>Old pages written before (or in spite of) the standardization wave don’t have a doctype. Therefore ’no doctype’ would mean quirks mode: show according to old rules.</li> <li>Contrarily, if the web developer was savvy enough to include a doctype, he probably knew what he was doing. Therefore most doctypes trigger strict mode: show according to pure standards.</li> <li>Any new or unknown doctype triggers strict mode.</li> <li>The problem was that some pages written in quirks mode did have doctypes. Therefore each browser has its own list with doctypes that trigger quirks mode. See this <a href="https://hsivonen.iki.fi/doctype/" class="external">browser comparison chart</a> for an overview of these lists.</li> </ul> <p>Note that your page does <b>not</b> have to validate according to the chosen doctype, the mere presence of the doctype tag is enough to trigger strict mode.</p> <p>On this site I use this doctype in most pages. In addition to declaring my pages XHTML 1.0 Transitional, it also triggers almost strict mode in all browsers.</p> <pre> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> </pre> <h4>Good solution?</h4> <p>Personally I’m not terribly happy with doctype switching. A doctype carries information about the flavour of (X)HTML you’re using, in other words, about document structure. In my opinion it shouldn’t carry any information about document <b>presentation</b>, because that violates the separation of structure and presentation that CSS is all about.</p> <p>But the browser vendors were not to be denied: browser after browser implemented doctype switching, and nowadays all modern browsers support it.</p> <h4>Complication: almost strict mode</h4> <p>In the early days, experiments with strict mode invariably raised the comment that images suddenly got an odd bottom margin that couldn’t be removed. The cause was that in strict mode <code><img /></code> is an inline element, which means that some space should be reserved for possible descender characters like g, j, or q. Of course an image doesn’t have descender characters, so the space was never used, but it still had to be reserved.</p> <p>The solution was to explicitly declare images block level elements: <code>img {display: block}</code>.</p> <p>Nonetheless browser vendors, Mozilla especially, thought this was such a confusing situation that they introduced "almost strict mode". This was defined as strict mode, but with images continuing to be blocks, and not inline elements.</p> <p>Most common doctypes, including the one I use, trigger almost strict mode. The treatment of images is by far the most important difference between almost strict mode and really strict mode.</p> <h4>IE Windows special: the xml prolog</h4> <p>In IE 6 Windows, Microsoft implemented one extra rule: if a doctype that triggers strict mode is preceded by an xml prolog, the page shows in quirks mode. This was done to allow web developers to achieve valid pages (which require a doctype) but nonetheless stay in quirks mode.</p> <p>This is the xml prolog. You should put it on the very first line of your document, <em>before</em> the doctype.</p> <pre> <?xml version="1.0" encoding="iso-8859-1"?> </pre> <p>Note that this behaviour has been removed from IE 7.</p> <h3>The differences</h3> <p>What, exactly, are the differences between the two modes? There are a few more differences that can trip up the unwary web developer. The table below summarizes a few of the most important ones.</p> <p>IE Quirks Mode is IE5.5, by the way. IE6, 7 and 8 all switch back to 5.5 when they encounter a Quirks Mode page.</p> <table cellspacing="5"> <tr> <td class="comp yes">Always</td> <td>Always supports standard</td> </tr> <tr> <td class="comp no">Never</td> <td>Never supports standard</td> </tr> <tr> <td class="comp incomplete">Depends</td> <td>Standards support depends on rendering mode; see text for details</td> </tr> </table> <table class="compatibility wide" cellspacing="5"> <col /> <col span="3" class="IE" /> <col span="3" class="FF" /> <col span="3" class="Saf" /> <col span="1" class="Chrome" /> <col span="2" class="Op" /> <col span="1" class="Rest" /> <tr class="compheader"> <th>Selector</th> <th>IE 6</th> <th>IE 7</th> <th>IE8b2</th> <th>FF 2</th> <th>FF 3.0</th> <th>FF 3.1b</th> <th>Saf 3.0 Win</th> <th>Saf 3.1 Win</th> <th>iPhone 3G</th> <th>Chrome 0.3</th> <th>Opera 9.51</th> <th>Opera 9.62</th> <th>Konqueror 3.5.7</th> </tr> <!-- BOX MODEL --> <tr> <td class="declaration" rowspan="2"> <div class="name">Box model</div> <a href="modes/box_quirks.html">Test page Quirks</a><br /> <a href="modes/box_strict.html">Test page Strict</a> </td> <td class="comp incomplete" colspan="3">Depends</td> <td class="comp yes" colspan="3">Always</td> <td class="comp yes" colspan="3">Always</td> <td class="comp yes">Always</td> <td class="comp yes" colspan="2">Always</td> <td class="comp yes">Always</td> </tr> <tr> <td colspan="15"> <p><strong>Standard</strong>: There are <a href="box.html">two box models</a>, the traditional and the W3C. Obviously, the W3C one, where the <code>width</code> excludes padding and borders, is the standard.</p> <p>In IE, the rendering mode decides which box model it follows. In quirks mode it uses the traditional model, in strict mode the W3C model.</p> <p>Doctype switching is the <em>only</em> way of selecting a box model in IE 6 Windows. Mozilla, Opera and IE Mac allow the use of the <code>box-sizing</code> declaration to select a box model, while Safari only supports the W3C box model.</p> <p>Exception: buttons elements always retain the traditional box model in IE Windows and Mozilla. <a href="tests/mozie_button.html">Test page</a>.</p> </td> </tr> <!-- WHITE-SPACE --> <tr> <td class="declaration" rowspan="2"> <div class="name">white-space: pre</div> <a href="modes/whitespace_quirks.html">Test page Quirks</a><br /> <a href="modes/whitespace_strict.html">Test page Strict</a> </td> <td class="comp incomplete" colspan="3">Depends</td> <td class="comp yes" colspan="3">Always</td> <td class="comp yes" colspan="3">Always</td> <td class="comp yes">Always</td> <td class="comp yes" colspan="2">Always</td> <td class="comp yes">Always</td> </tr> <tr> <td colspan="15"> <p><strong>Standard</strong>: <a href="whitespace.html"><code>white-space: pre</code></a> always works.</p> <p>In IE Windows this declaration works only in strict mode.</p> </td> </tr> <!-- MARGIN: AUTO --> <tr> <td class="declaration" rowspan="2"> <div class="name">margin and width: auto</div> <a href="modes/marginauto_quirks.html">Test page Quirks</a><br /> <a href="modes/marginauto_strict.html">Test page Strict</a> </td> <td class="comp incomplete" colspan="3">Depends</td> <td class="comp yes" colspan="3">Always</td> <td class="comp yes" colspan="3">Always</td> <td class="comp yes">Always</td> <td class="comp yes" colspan="2">Always</td> <td class="comp yes">Always</td> </tr> <tr> <td colspan="15"> <p><strong>Standard</strong>: By giving an element any <code>width</code> and <code>margin: 0 auto</code> it’s possible to center it.</p> <p>In IE Windows this only works in strict mode.</p> </td> </tr> <!-- UNITLESS VALUES --> <tr> <td class="declaration" rowspan="2"> <div class="name">Unitless values are ignored</div> <a href="modes/unitless_quirks.html">Test page Quirks</a><br /> <a href="modes/unitless_strict.html">Test page Strict</a> </td> <td class="comp incomplete" colspan="3">Depends</td> <td class="comp incomplete" colspan="3">Depends</td> <td class="comp incomplete" colspan="3">Depends</td> <td class="comp incomplete">Depends</td> <td class="comp incomplete" colspan="2">Depends</td> <td class="comp incomplete">Depends</td> </tr> <tr> <td colspan="15"> <p><strong>Standard</strong>: CSS requires most values to have a unit. If such a value doesn’t have a unit it’s ignored.</p> <p>However, in quirks mode all browsers automatically append the unit <code>px</code> to unitless values.</p> </td> </tr> <tr class="compheader"> <th>Selector</th> <th>IE 6</th> <th>IE 7</th> <th>IE8b2</th> <th>FF 2</th> <th>FF 3.0</th> <th>FF 3.1b</th> <th>Saf 3.0 Win</th> <th>Saf 3.1 Win</th> <th>iPhone 3G</th> <th>Chrome 0.3</th> <th>Opera 9.51</th> <th>Opera 9.62</th> <th>Konqueror 3.5.7</th> </tr> <!-- .TEST:HOVER --> <tr> <td class="declaration" rowspan="2"> <div class="name">.test:hover</div> <a href="modes/hover_quirks.html">Test page Quirks</a><br /> <a href="modes/hover_strict.html">Test page Strict</a> </td> <td class="comp untestable">Untest<wbr />able</td> <td class="comp incomplete" colspan="2">Depends</td> <td class="comp incomplete" colspan="3">Depends</td> <td class="comp yes" colspan="2">Always</td> <td class="comp untestable">Untest<wbr />able</td> <td class="comp yes">Always</td> <td class="comp yes" colspan="2">Always</td> <td class="comp yes">Always</td> </tr> <tr> <td colspan="15"> <p><strong>Standard</strong>: The <code>.test:hover</code> selector (without an element selector like <code>p.test:hover</code>) always works.</p> <p>It does not work in some browsers quirks mode.</p> </td> </tr> <!-- IMG DISPLAY --> <tr> <td class="declaration" rowspan="2"> <div class="name">img display</div> <a href="modes/imgdisplay_quirks.html">Test page Quirks</a><br /> <a href="modes/imgdisplay_strict.html">Test page Strict</a> </td> <td class="comp no" colspan="2">Never</td> <td class="comp incomplete">Depends</td> <td class="comp incomplete" colspan="3">Depends</td> <td class="comp incomplete" colspan="3">Depends</td> <td class="comp incomplete">Depends</td> <td class="comp incomplete" colspan="2">Depends</td> <td class="comp incomplete">Depends</td> </tr> <tr> <td colspan="15"> <p><strong>Standard</strong>: An image has <code>display: inline</code> by default. Therefore it has a slight space below it, because the image is placed on the baseline of the text. Below the baseline there should be some more space for the descender characters like g, j or q.</p> <p>In quirks mode <code>img</code> has a default <code>display: block</code>, while in really strict mode it has a default <code>display: inline</code>. The offshoot is that in strict mode it’s not possible to make a container fit tightly around the image, unless, of course, you explicitly say <code>img {display: block}</code>.</p> <p>Note that the strict mode test page is in "really strict mode" instead of the "almost strict mode" I use on the rest of this site. See above for more information on almost strict mode.</p> </td> </tr> <!-- OVERFLOW: VISIBLE --> <tr> <td class="declaration" rowspan="2"> <div class="name">overflow: visible</div> <a href="modes/overflow_quirks.html">Test page Quirks</a><br /> <a href="modes/overflow_strict.html">Test page Strict</a> </td> <td class="comp no">Never</td> <td class="comp incomplete" colspan="2">Depends</td> <td class="comp yes" colspan="3">Always</td> <td class="comp yes" colspan="3">Always</td> <td class="comp yes">Always</td> <td class="comp incomplete" colspan="2">Depends</td> <td class="comp yes">Always</td> </tr> <tr> <td colspan="15"> <p><strong>Standard</strong>: When you give an element a fixed <code>height</code> and an <a href="overflow.html"><code>overflow: visible</code></a> (which is the default anyway), and the content is too long for the element, the content should flow out of the element.</p> <p>IE 6 <em>always</em> stretches up the element to accomodate all the content, regardless of rendering mode.</p> <p>In Opera and IE 7 this only happens in quirks mode.</p> </td> </tr> <!-- WIDTH ON INLINE ELEMENTS --> <tr> <td class="declaration" rowspan="2"> <div class="name">width on inline elements</div> <a href="modes/widthinline_quirks.html">Test page Quirks</a><br /> <a href="modes/widthinline_strict.html">Test page Strict</a> </td> <td class="comp incomplete" colspan="3">Depends</td> <td class="comp yes" colspan="3">Always</td> <td class="comp yes" colspan="3">Always</td> <td class="comp yes">Always</td> <td class="comp yes" colspan="2">Always</td> <td class="comp yes">Always</td> </tr> <tr> <td colspan="15"> <p><strong>Standard</strong>: An inline element such as a <code><span></code> cannot have a <code>width</code>.</p> <p>In quirks mode, however, IE tries to honour a <code>width</code> by giving the element <code>display: inline-block</code>, which does allow a <code>width</code> declaration.</p> </td> </tr> <!-- FONT SIZE OF TDS --> <tr> <td class="declaration" rowspan="2"> <div class="name">font sizes of table cells</div> <a href="modes/td_quirks.html">Test page Quirks</a><br /> <a href="modes/td_strict.html">Test page Strict</a> </td> <td class="comp incomplete" colspan="3">Depends</td> <td class="comp incomplete" colspan="3">Depends</td> <td class="comp incomplete" colspan="2">Depends</td> <td class="comp">?</td> <td class="comp incomplete">Depends</td> <td class="comp incomplete" colspan="2">Depends</td> <td class="comp incomplete">Depends</td> </tr> <tr> <td colspan="15"> <p><strong>Standard</strong>: <code>td {font-size: 80%}</code> should mean that TDs get a font size of 80% of the <code>body</code> text.</p> <p>However, in quirks mode it means that TDs get a font size of 80% of the default browser font size (usually 16px). This is a really odd behaviour, because it’s based on a bug in Netscape 4 (!), and for some reason all browser vendors thought it necessary to perpetuate this bug.</p> <p>The iPhone in Quirks Mode seems to make the text slightly smaller than the normal body text, although the Strict Mode text is smaller still. I’m not sure how to interpret this.</p> </td> </tr> <tr class="compheader"> <th>Selector</th> <th>IE 6</th> <th>IE 7</th> <th>IE8b2</th> <th>FF 2</th> <th>FF 3.0</th> <th>FF 3.1b</th> <th>Saf 3.0 Win</th> <th>Saf 3.1 Win</th> <th>iPhone 3G</th> <th>Chrome 0.3</th> <th>Opera 9.51</th> <th>Opera 9.62</th> <th>Konqueror 3.5.7</th> </tr> </table> <p>Further information can be found at <a href="http://www.cs.tut.fi/~jkorpela/quirks-mode.html" class="external">Jukka K. Korpela’s Quirks Mode features page</a>.</p> <div id="footer"><a href="/home.html">Home</a> <a href="/sitemap.html">Sitemap</a> <p class="smaller" id="validation">Invalid XHTML 1.0 because this page uses <wbr /></p> </div> </body> </html>