1. Introduction
1.1. History
Browsers have several rendering modes to render HTML documents. The reason for this is basically a historical accident. The CSS specification was incompatible with the behavior of existing browsers which existing Web content relied on. In order to comply with the specification while not breaking existing content, browsers introduced a new rendering mode (no-quirks mode). Some browsers still had the shrink-wrapping behavior for images in table cells in their no-quirks mode, and sites started relying on that, so browsers that implemented the specification’s behavior introduced a third mode (limited-quirks mode). In hindsight, it would have been better to make the default CSS behavior be compatible with what the existing content relied on and providing opt-ins to different behavior. The different modes have since gained a few differences outside of CSS.
1.2. Goals
-
Create a specification for rendering old (or indeed new, if they happen to have a particular pragma) HTML documents.
-
Remove quirks from implementations that are not needed for Web compatibility.
-
Get interoperability on quirks that are needed for Web compatibility.
-
Where possible, limit quirks to a fixed set of legacy features so they don’t propagate into new features.
This specification does not enumerate all quirks that currently exist in browsers. A number of quirks are specified in HTML, DOM, CSSOM and CSSOM View. [HTML] [DOM] [CSSOM] [CSSOM-VIEW] If a quirk is not specified anywhere, it is probably due to the second bullet point above.
2. Common infrastructure
2.1. Conformance
All diagrams, examples, and notes in this specification are non-normative, as are all sections explicitly marked non-normative. Everything else in this specification is normative.
The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this specification are to be interpreted as described in RFC2119. For readability, these words do not appear in all uppercase letters in this specification. [RFC2119]
2.2. Terminology
When this specification refers to a "foo element", it means an element with the
local name foo and having the namespace http://www.w3.org/1999/xhtml.
When this specification refers to a "foo attribute", it means an attribute with
the local name foo and having no namespace.
3. CSS
3.1. The hashless hex color quirk
Quirky colors are denoted by <quirky-color>. A quirky color corresponds to a <number-token>, a <dimension-token> or an <ident-token> component value in the syntax. The value of a quirky color is obtained from the possible component values using the following algorithm, aborting on the first step that returns a value:
-
Let cv be the component value.
-
If cv is a <number-token> or a <dimension-token>, follow these substeps:
-
If cv’s type flag is not "integer", return an error.
This means that values that happen to use scientific notation, e.g.,
5e5e5e, will fail to parse. -
If cv’s value is less than zero, return an error.
-
Let serialization be the serialization of cv’s value, as a base-ten integer using digits 0-9 (U+0030 to U+0039) in the shortest form possible.
-
If cv is a <dimension-token>, append the unit to serialization.
-
If serialization consists of fewer than six characters, prepend zeros (U+0030) so that it becomes six characters.
-
-
Otherwise, cv is an <ident-token>; let serialization be cv’s value.
-
If serialization does not consist of three or six characters, return an error.
-
If serialization contains any characters not in the range [0-9A-Fa-f] (U+0030 to U+0039, U+0041 to U+0046, U+0061 to U+0066), return an error.
-
Return the concatenation of "
#" (U+0023) and serialization.
If the value of a quirky color is an error, it is an illegal value. Otherwise, the value of a quirky color must be interpreted as an RGB value in hexadecimal notation using the same rules as for <color>.
In quirks mode, the following properties must have their "Value" grammar changed by replacing <color> with:
[ <color> | <quirky-color> ]
- background-color
- border-color
- border-top-color
- border-right-color
- border-bottom-color
- border-left-color
- color
Any property not listed above must not support <quirky-color> even if it references one of the above properties in its "Value" grammar.
This quirk must apply inside an @supports at-rule.
The <quirky-color> value must not be supported in arguments to CSS expressions, and must not be
supported in the supports() static
method of the CSS interface.
3.2. The unitless length quirk
Quirky lengths are denoted by <quirky-length>. A quirky length is a number and corresponds to a <number-token> component value in the syntax. The value of a quirky length is obtained from the component value’s value.
The value of a quirky length must be interpreted as a <length> where the unit is px.
In quirks mode, the following properties must have their "Value" grammar changed by replacing <length> with:
[ <length> | <quirky-length> ]
- background-position
- border-spacing
- border-top-width
- border-right-width
- border-bottom-width
- border-left-width
- border-width
- bottom
- clip
- font-size
- height
- left
- letter-spacing
- margin-right
- margin-left
- margin-top
- margin-bottom
- margin
- max-height
- max-width
- min-height
- min-width
- padding-top
- padding-right
- padding-bottom
- padding-left
- padding
- right
- text-indent
- top
- vertical-align
- width
- word-spacing
Any property not listed above must not support <quirky-length> even if it references one of the above properties in its "Value" grammar.
This quirk must apply inside an @supports at-rule.
The <quirky-length> value must not be supported in arguments to CSS expressions other than the rect() expression, and must not be supported in the supports() static method of the CSS interface.
3.3. The line height calculation quirk
In quirks mode and limited-quirks mode, an inline box that matches the following conditions, must, for the purpose of line height calculation, act as if the box had a line-height of zero.
-
The border-right-width, border-left-width, padding-right and padding-left properties have a used value of zero.
-
It either contains no text or it contains only collapsed whitespace.
3.4. The blocks ignore line-height quirk
In quirks mode and limited-quirks mode, for a block container element whose content is composed of inline-level elements, the element’s line-height must be ignored for the purpose of calculating the minimal height of line boxes within the element.
This means that the "strut" is not created.
3.5. The percentage height calculation quirk
In quirks mode, for the purpose of calculating the height of an element element, if the computed value of the position property of element is relative or static, the specified value for the height property of element is a <percentage>, and element does not have a computed value of the display property that is table-row, table-row-group, table-header-group, table-footer-group, table-cell or table-caption, the containing block of element must be calculated using the following algorithm, aborting on the first step that returns a value:
-
Let element be the nearest ancestor block container box of element, if there is one. Otherwise, return the initial containing block.
-
If element has a computed value of the display property that is table-cell, return a UA-defined value.
-
If element has a computed value of the height property that is not auto, return element.
-
If element has a computed value of the position property that is absolute, return element.
-
If element is a
bodyelement, and its parent is the document element, and that is anhtmlelement, let element have a quirky containing block height and return element. -
Jump to the first step.
When an element body is said to have a quirky containing block height, the containing block the element establishes must act as if it had a height calculated using the following algorithm:
-
If the document element has a computed value of the height property that is auto and has a computed value of the position property that is absolute, return auto and abort these steps.
-
Let elements be an array with body as its only item.
-
If the document element has a computed value of the height property that is not auto, let A be the used value of the height property of the document element. Otherwise, let A be the height of the initial containing block and append the document element to elements.
-
Let B be the sum of the used values of the margin-top, margin-bottom, border-top-width, border-bottom-width, padding-top and padding-bottom properties of each element in elements.
-
Let result be A minus B.
-
If result is negative, let result be zero.
-
Return result.
It is at the time or writing undefined how percentage heights inside tables work in CSS. This specification does not try to specify what to use as the containing block for calculating percentage heights in tables. Godspeed!
3.6. The table cell width calculation quirk
In quirks mode, for the purpose of calculating the min-content width of an
inline formatting context for which a table cell cell is the containing block, if cell has a computed value of the width property that is auto, img elements
that are inline-level replaced elements in that inline formatting context must
not have a soft wrap opportunity before or after them. [CSS-TEXT-3] [INTRINSIC]
3.7. The table cell nowrap minimum width calculation quirk
In quirks mode, an element cell that matches the following conditions must act as if it had an outer min-content width of a table cell in the automatic table layout algorithm that is the bigger value of cell’s computed value of the width property and the outer min-content width of a table cell. [INTRINSIC]
-
cell has a
nowrapattribute. -
The computed value of the width property of cell is a <length> that is not zero.
3.8. The collapsing table quirk
In quirks mode, an element table that matches the following conditions must have a used value of the height property of 0 and a used value of the border-style property of none.
-
table has a computed value of the display property that is table.
-
table has no child table-row-group, table-header-group, table-footer-group or table-caption box.
-
table has no child table-column-group box that itself has a child table-column box.
3.9. The text decoration doesn’t propagate into tables quirk
In quirks mode, text decoration must not propagate
into table elements.
3.10. The tables inherit color from body quirk
In quirks mode, the initial value of the color property must be quirk-inherit, a special value that has no keyword mapping to it.
The computed value of the color property of an element element must be calculated using the following algorithm:
-
If the specified value of the color property of element is not quirk-inherit, jump to the last step.
-
If element is not a
tableelement, jump to the last step. -
If the document’s body element is null, jump to the last step.
-
Return the used value of the color property of the document’s body element. Abort these steps.
-
If the specified value of the color property of element is quirk-inherit, let the specified value of the color property of element be the initial value of the color property according to the CSS specification. Return the computed value of the color property of element as specified in the CSS specification.
The document’s body element is the first child of the document element that is a body element, if there is one, and the document element is an html element. Otherwise it is null.
3.11. The table cell height box sizing quirk
In quirks mode, elements that have a computed value of the display property of table-cell must act as they have used value of the box-sizing property of border-box, but only for the purpose of the height, min-height and max-height properties.
4. Selectors
4.1. The :active and :hover quirk
In quirks mode, a compound selector selector that matches the following conditions must not match elements that would not also match the :any-link selector. [SELECTORS4]
-
selector uses the :active or :hover pseudo-classes.
-
selector does not use a type selector.
-
selector does not use an attribute selector.
-
selector does not use an ID selector.
-
selector does not use a class selector.
-
selector does not use a pseudo-class selector other than :active and :hover.
-
selector does not use a pseudo-element selector.
-
selector is not part of an argument to a functional pseudo-class or pseudo-element.
Acknowledgments
Thanks to Anne van Kesteren, Boris Zbarsky, Chris Rebert, David Baron, Kang-Hao Lu, Ms2ger, Simon Sapin, and Tab Atkins for their useful comments.
Special thanks to Boris Zbarsky and David Baron for documenting Mozilla’s quirks in MDN.
This standard is written by Simon Pieters (Opera Software ASA, simonp@opera.com).
Per CC0, to the extent possible under law, the editors have waived all copyright and related or neighboring rights to this work.