CANONICALIZATION OF CASCADING STYLE SHEET VALUES ================================================ Introduction ------------ There are several times when user agents may need to have a canonical representation of CSS. For example, DOM calls should return CSS in a canonical form so that scripts do not have to contain entire CSS parsers just to animate one property. Editors may also wish to use the canonical form of CSS when presenting it to the user. There are several steps to canonicalizing CSS. This module concerns itself merely with the canonicalisation of CSS Values. The CSS Syntax module may list rules for canonicalization of an overall CSS file, and the W3C Selectors module may list rules for how to canonicalize selectors used in CSS or other languages. Rules ----- To canonicalise the value of a property, a UA must use the following steps, in the following order (or behave as if it did). * Relative lengths ('em', 'ex', 'px', all the font-size keywords, and '%') do not have their units changed. However, absolute lengths must be given in millimeters. For example, the canonical version of "+012.0pt" is "4.2333mm" (give or take a few significant figures). Note. _Computed_ values may well be in different units than the specified value. UAs should use 'px' or 'mm' as their final units for computed length values. * When a of zero is given, then any specified units should be removed. * Colours (other than system colours, see below) are canonicalized to the six-hex-digit #RRGGBB syntax if their alpha component is exactly 1.0, and the rgba(r, g, b, a) syntax with integer arguments if the alpha component is less than 1.0. For example, rgb(0%,100%,0%) becomes #00FF00, but hsla(120,100%,50%,0.9) becomes rgba(0, 255, 0, 0.9). Note that this means that implementations with color values internally stored with more than 32 bits will lose data during serialisation. * System colours are left in their keyword form. * The colour 'transparent' canonicalises to 'transparent' unless the UA supports rgba() colours, in which case it canonicalises to 'rgba(0, 0, 0, 0)'. * Angles are canonicalized to 'deg' and normalized to the range of their property. For example, 'azimuth: 700grad' would be canonicalized to 'azimuth: 270deg'. This also applies to angle keywords as used in the 'elevation' and 'azimuth' properties, they are canonicalized to their value in degrees. * Times are canonicalized to seconds ('s'). * Frequencies are canonicalized to Hertz ('Hz'). * For all integers and real numbers, including those with units, these canonicalization steps must be followed: If the number is zero, the canonical result is the literal string '0' plus any units (for lengths, the unit identifier will have been removed before this step). Otherwise, leading and trailing zeros should be omitted, any leading '+' must be omitted, the decimal point in a real number must be omitted unless there is a fractional part, and if the number is in the range -1 < x < 1, then one leading zero must be inserted before the decimal point. The number of given significant figures is completely UA dependent. * Where multiple values may appear in any order without changing the meaning of the value (typically represented by a double bar || in the value syntax), UAs should use the canonical order as given in the syntax (e.g. " " for the 'border' short-hand property). * When repeated values may be omitted without changing the meaning of the value (e.g. as in the margin and padding properties), then the fewest number of values should be given. * Where white space may be removed without changing the meaning of the value, then it should be removed. * and values should be quoted. * Double quotes (rather than single quotes) shall be used for string quotation. (When changing from single quotes to double quotes, double quotes already in the string must be escaped.) * The quotes in the form should be removed. (Parenthesises that were in the string, along with any other characters not legal when the string is not quoted (such as commas), must be escaped.) * Unnecessary escapes should be removed. (For example, "\z" should be represented as "z". This extends to unescaping UNICODE escapes, except, of course, if the encoding cannot contain those characters!) * Where components of the value may be dropped without changing the meaning of the value (for example, initial values in shorthand properties), then they should be removed. If this would remove all the values, then the first allowed value must be given (For example, for 'background' that would be 'transparent' (which itself would canonicalise to rgba(0,0,0,0)) since 'background-color' is the first component of the value; for 'border' it would be '0' since the first component of that value is 'border-width'). * A single space should be added after each comma that is not part of a string, except where that would change the meaning of the value. For example: foo,bar,baz ...should become: foo, bar, baz * Whenever case is insensitive, for example in property or counter names, the text should be changed to the canonical case as given in the syntax definition. For example, the canonical value of COUNTER( PAR-NUM,UPPER-ROMAN ) DISC ...is counter(par-num, upper-roman) disc ...but the colour 'WINDOWTEXT' becomes 'WindowText'. Examples -------- These steps should guarantee that there is no data loss, from a CSS point of view, other than for color values on systems with colors stored with more than 32 bits. Here are some examples of 'before' and 'after' results on specified values. The 'before' column could be what the author wrote in a stylesheet, while the 'after' column shows what querying the DOM should return. BEFORE AFTER background: none; background: rgba(0, 0, 0, 0); outline: none; outline: invert; border: none; border: medium; list-style: none; list-style: disc; margin: 0px 1px 1px 1px ; margin: 0 1px 1px; azimuth: behind left; azimuth: 220deg; font-family: a, 'b"', serif; font-family: "a", "b\"", serif; content: url('h)i') '\[\]'; content: url(h\)i) "[]"; azimuth: leftwards; azimuth: leftwards; color: rgb(18, 52, 86); color: #123456; color: rgba(0.00001, 0, 0, 1); color: #000000;