Table of contents
    1. 2.5 Common microsyntaxes
      1. 2.5.1 Common parser idioms
      2. 2.5.2 Boolean attributes
      3. 2.5.3 Keywords and enumerated attributes
      4. 2.5.4 Numbers
        1. 2.5.4.1 Non-negative integers
        2. 2.5.4.2 Signed integers
        3. 2.5.4.3 Real numbers
        4. 2.5.4.4 Percentages and lengths
        5. 2.5.4.5 Lists of integers
        6. 2.5.4.6 Lists of dimensions
      5. 2.5.5 Dates and times
        1. 2.5.5.1 Months
        2. 2.5.5.2 Dates
        3. 2.5.5.3 Times
        4. 2.5.5.4 Local dates and times
        5. 2.5.5.5 Global dates and times
        6. 2.5.5.6 Weeks
        7. 2.5.5.7 Vaguer moments in time
      6. 2.5.6 Colors
      7. 2.5.7 Space-separated tokens
      8. 2.5.8 Comma-separated tokens
      9. 2.5.9 References
      10. 2.5.10 Media queries

2.5 Common microsyntaxes

There are various places in HTML that accept particular data types, such as dates or numbers. This section describes what the conformance criteria for content in those formats is, and how to parse them.

Implementors are strongly urged to carefully examine any third-party libraries they might consider using to implement the parsing of syntaxes described below. For example, date libraries are likely to implement error handling behavior that differs from what is required in this specification, since error-handling behavior is often not defined in specifications that describe date syntaxes similar to those used in this specification, and thus implementations tend to vary greatly in how they handle errors.

2.5.1 Common parser idioms

The space characters, for the purposes of this specification, are U+0020 SPACE, U+0009 CHARACTER TABULATION (tab), U+000A LINE FEED (LF), U+000C FORM FEED (FF), and U+000D CARRIAGE RETURN (CR).

The White_Space characters are those that have the Unicode property "White_Space" in the Unicode PropList.txt data file. [UNICODE]

This should not be confused with the "White_Space" value (abbreviated "WS") of the "Bidi_Class" property in the Unicode.txt data file.

The alphanumeric ASCII characters are those in the ranges U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), U+0041 LATIN CAPITAL LETTER A to U+005A LATIN CAPITAL LETTER Z, U+0061 LATIN SMALL LETTER A to U+007A LATIN SMALL LETTER Z.

Some of the micro-parsers described below follow the pattern of having an input variable that holds the string being parsed, and having a position variable pointing at the next character to parse in input.

For parsers based on this pattern, a step that requires the user agent to collect a sequence of characters means that the following algorithm must be run, with characters being the set of characters that can be collected:

  1. Let input and position be the same variables as those of the same name in the algorithm that invoked these steps.

  2. Let result be the empty string.

  3. While position doesn't point past the end of input and the character at position is one of the characters, append that character to the end of result and advance position to the next character in input.

  4. Return result.

The step skip whitespace means that the user agent must collect a sequence of characters that are space characters. The step skip White_Space characters means that the user agent must collect a sequence of characters that are White_Space characters. In both cases, the collected characters are not used. [UNICODE]

When a user agent is to strip line breaks from a string, the user agent must remove any U+000A LINE FEED (LF) and U+000D CARRIAGE RETURN (CR) characters from that string.

When a user agent is to strip leading and trailing whitespace from a string, the user agent must remove all space characters that are at the start or end of the string.

The code-point length of a string is the number of Unicode code points in that string.

2.5.2 Boolean attributes

A number of attributes are boolean attributes. The presence of a boolean attribute on an element represents the true value, and the absence of the attribute represents the false value.

If the attribute is present, its value must either be the empty string or a value that is an ASCII case-insensitive match for the attribute's canonical name, with no leading or trailing whitespace.

The values "true" and "false" are not allowed on boolean attributes. To represent a false value, the attribute has to be omitted altogether.

Here is an example of a checkbox that is checked and disabled. The checked and disabled attributes are the boolean attributes.

<label><input type=checkbox checked name=cheese disabled> Cheese</label>

This could be equivalently written as this:

<label><input type=checkbox checked=checked name=cheese disabled=disabled> Cheese</label>

You can also mix styles; the following is still equivalent:

<label><input type='checkbox' checked name=cheese disabled=""> Cheese</label>

2.5.3 Keywords and enumerated attributes

Some attributes are defined as taking one of a finite set of keywords. Such attributes are called enumerated attributes. The keywords are each defined to map to a particular state (several keywords might map to the same state, in which case some of the keywords are synonyms of each other; additionally, some of the keywords can be said to be non-conforming, and are only in the specification for historical reasons). In addition, two default states can be given. The first is the invalid value default, the second is the missing value default.

If an enumerated attribute is specified, the attribute's value must be an ASCII case-insensitive match for one of the given keywords that are not said to be non-conforming, with no leading or trailing whitespace.

When the attribute is specified, if its value is an ASCII case-insensitive match for one of the given keywords then that keyword's state is the state that the attribute represents. If the attribute value matches none of the given keywords, but the attribute has an invalid value default, then the attribute represents that state. Otherwise, if the attribute value matches none of the keywords but there is a missing value default state defined, then that is the state represented by the attribute. Otherwise, there is no default, and invalid values must be ignored.

When the attribute is not specified, if there is a missing value default state defined, then that is the state represented by the (missing) attribute. Otherwise, the absence of the attribute means that there is no state represented.

The empty string can be a valid keyword.

2.5.4 Numbers

2.5.4.1 Non-negative integers

A string is a valid non-negative integer if it consists of one or more characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9).

A valid non-negative integer represents the number that is represented in base ten by that string of digits.

The rules for parsing non-negative integers are as given in the following algorithm. When invoked, the steps must be followed in the order given, aborting at the first step that returns a value. This algorithm will return either zero, a positive integer, or an error.

  1. Let input be the string being parsed.

  2. Let position be a pointer into input, initially pointing at the start of the string.

  3. Skip whitespace.

  4. If position is past the end of input, return an error.

  5. If the character indicated by position is a U+002B PLUS SIGN character (+), advance position to the next character. (The "+" is ignored, but it is not conforming.)

  6. If position is past the end of input, return an error.

  7. If the character indicated by position is not one of U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then return an error.

  8. Collect a sequence of characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), and interpret the resulting sequence as a base-ten integer. Let value be that integer.

  9. Return value.

2.5.4.2 Signed integers

A string is a valid integer if it consists of one or more characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), optionally prefixed with a U+002D HYPHEN-MINUS character (-).

A valid integer without a U+002D HYPHEN-MINUS (-) prefix represents the number that is represented in base ten by that string of digits. A valid integer with a U+002D HYPHEN-MINUS (-) prefix represents the number represented in base ten by the string of digits that follows the U+002D HYPHEN-MINUS, subtracted from zero.

The rules for parsing integers are similar to the rules for non-negative integers, and are as given in the following algorithm. When invoked, the steps must be followed in the order given, aborting at the first step that returns a value. This algorithm will return either an integer or an error.

  1. Let input be the string being parsed.

  2. Let position be a pointer into input, initially pointing at the start of the string.

  3. Let sign have the value "positive".

  4. Skip whitespace.

  5. If position is past the end of input, return an error.

  6. If the character indicated by position (the first character) is a U+002D HYPHEN-MINUS character (-):

    1. Let sign be "negative".
    2. Advance position to the next character.
    3. If position is past the end of input, return an error.

    Otherwise, if the character indicated by position (the first character) is a U+002B PLUS SIGN character (+):

    1. Advance position to the next character. (The "+" is ignored, but it is not conforming.)
    2. If position is past the end of input, return an error.
  7. If the character indicated by position is not one of U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then return an error.

  8. Collect a sequence of characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), and interpret the resulting sequence as a base-ten integer. Let value be that integer.

  9. If sign is "positive", return value, otherwise return the result of subtracting value from zero.

2.5.4.3 Real numbers

A string is a valid floating point number if it consists of:

  1. Optionally, a U+002D HYPHEN-MINUS character (-).
  2. A series of one or more characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9).
  3. Optionally:
    1. A single U+002E FULL STOP character (.).
    2. A series of one or more characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9).
  4. Optionally:
    1. Either a U+0065 LATIN SMALL LETTER E character (e) or a U+0045 LATIN CAPITAL LETTER E character (E).
    2. Optionally, a U+002D HYPHEN-MINUS character (-) or U+002B PLUS SIGN character (+).
    3. A series of one or more characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9).

A valid floating point number represents the number obtained by multiplying the significand by ten raised to the power of the exponent, where the significand is the first number, interpreted as base ten (including the decimal point and the number after the decimal point, if any, and interpreting the significand as a negative number if the whole string starts with a U+002D HYPHEN-MINUS character (-) and the number is not zero), and where the exponent is the number after the E, if any (interpreted as a negative number if there is a U+002D HYPHEN-MINUS character (-) between the E and the number and the number is not zero, or else ignoring a U+002B PLUS SIGN character (+) between the E and the number if there is one). If there is no E, then the exponent is treated as zero.

The Infinity and Not-a-Number (NaN) values are not valid floating point numbers.

The best representation of the number n as a floating point number is the string obtained from applying the JavaScript operator ToString to n. The JavaScript operator ToString is not uniquely determined. When there are multiple possible strings that could be obtained from the JavaScript operator ToString for a particular value, the user agent must always return the same string for that value (though it may differ from the value used by other user agents).

The rules for parsing floating point number values are as given in the following algorithm. This algorithm must be aborted at the first step that returns something. This algorithm will return either a number or an error.

  1. Let input be the string being parsed.

  2. Let position be a pointer into input, initially pointing at the start of the string.

  3. Let value have the value 1.

  4. Let divisor have the value 1.

  5. Let exponent have the value 1.

  6. Skip whitespace.

  7. If position is past the end of input, return an error.

  8. If the character indicated by position is a U+002D HYPHEN-MINUS character (-):

    1. Change value and divisor to −1.
    2. Advance position to the next character.
    3. If position is past the end of input, return an error.

    Otherwise, if the character indicated by position (the first character) is a U+002B PLUS SIGN character (+):

    1. Advance position to the next character. (The "+" is ignored, but it is not conforming.)
    2. If position is past the end of input, return an error.
  9. If the character indicated by position is not one of U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then return an error.

  10. Collect a sequence of characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), and interpret the resulting sequence as a base-ten integer. Multiply value by that integer.

  11. If position is past the end of input, jump to the step labeled conversion.
  12. If the character indicated by position is a U+002E FULL STOP (.), run these substeps:

    1. Advance position to the next character.

    2. If position is past the end of input, or if the character indicated by position is not one of U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), U+0065 LATIN SMALL LETTER E (e), or U+0045 LATIN CAPITAL LETTER E (E), then jump to the step labeled conversion.

    3. If the character indicated by position is a U+0065 LATIN SMALL LETTER E character (e) or a U+0045 LATIN CAPITAL LETTER E character (E), skip the remainder of these substeps.

    4. Fraction loop: Multiply divisor by ten.

    5. Add the value of the character indicated by position, interpreted as a base-ten digit (0..9) and divided by divisor, to value.
    6. Advance position to the next character.

    7. If position is past the end of input, then jump to the step labeled conversion.

    8. If the character indicated by position is one of U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), jump back to the step labeled fraction loop in these substeps.

  13. If the character indicated by position is a U+0065 LATIN SMALL LETTER E character (e) or a U+0045 LATIN CAPITAL LETTER E character (E), run these substeps:

    1. Advance position to the next character.

    2. If position is past the end of input, then jump to the step labeled conversion.

    3. If the character indicated by position is a U+002D HYPHEN-MINUS character (-):

      1. Change exponent to −1.
      2. Advance position to the next character.
      3. If position is past the end of input, then jump to the step labeled conversion.

      Otherwise, if the character indicated by position is a U+002B PLUS SIGN character (+):

      1. Advance position to the next character.
      2. If position is past the end of input, then jump to the step labeled conversion.

    4. If the character indicated by position is not one of U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump to the step labeled conversion.

    5. Collect a sequence of characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), and interpret the resulting sequence as a base-ten integer. Multiply exponent by that integer.

    6. Multiply value by ten raised to the exponentth power.

  14. Conversion: Let S be the set of finite IEEE 754 double-precision floating point values except −0, but with two special values added: 21024 and −21024.

  15. Let rounded-value be the number in S that is closest to value, selecting the number with an even significand if there are two equally close values. (The two special values 21024 and −21024 are considered to have even significands for this purpose.)

  16. If rounded-value is 21024 or −21024, return an error.

  17. Return rounded-value.

2.5.4.4 Percentages and lengths

The rules for parsing dimension values are as given in the following algorithm. When invoked, the steps must be followed in the order given, aborting at the first step that returns a value. This algorithm will return either a number greater than or equal to 1.0, or an error; if a number is returned, then it is further categorized as either a percentage or a length.

  1. Let input be the string being parsed.

  2. Let position be a pointer into input, initially pointing at the start of the string.

  3. Skip whitespace.

  4. If position is past the end of input, return an error.

  5. If the character indicated by position is a U+002B PLUS SIGN character (+), advance position to the next character.

  6. Collect a sequence of characters that are U+0030 DIGIT ZERO (0) characters, and discard them.

  7. If position is past the end of input, return an error.

  8. If the character indicated by position is not one of U+0031 DIGIT ONE (1) to U+0039 DIGIT NINE (9), then return an error.

  9. Collect a sequence of characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), and interpret the resulting sequence as a base-ten integer. Let value be that number.

  10. If position is past the end of input, return value as a length.

  11. If the character indicated by position is a U+002E FULL STOP character (.):

    1. Advance position to the next character.

    2. If position is past the end of input, or if the character indicated by position is not one of U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then return value as a length.

    3. Let divisor have the value 1.

    4. Fraction loop: Multiply divisor by ten.

    5. Add the value of the character indicated by position, interpreted as a base-ten digit (0..9) and divided by divisor, to value.
    6. Advance position to the next character.

    7. If position is past the end of input, then return value as a length.

    8. If the character indicated by position is one of U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), return to the step labeled fraction loop in these substeps.

  12. If position is past the end of input, return value as a length.

  13. If the character indicated by position is a U+0025 PERCENT SIGN character (%), return value as a percentage.

  14. Return value as a length.

2.5.4.5 Lists of integers

A valid list of integers is a number of valid integers separated by U+002C COMMA characters, with no other characters (e.g. no space characters). In addition, there might be restrictions on the number of integers that can be given, or on the range of values allowed.

The rules for parsing a list of integers are as follows:

  1. Let input be the string being parsed.

  2. Let position be a pointer into input, initially pointing at the start of the string.

  3. Let numbers be an initially empty list of integers. This list will be the result of this algorithm.

  4. If there is a character in the string input at position position, and it is either a U+0020 SPACE, U+002C COMMA, or U+003B SEMICOLON character, then advance position to the next character in input, or to beyond the end of the string if there are no more characters.

  5. If position points to beyond the end of input, return numbers and abort.

  6. If the character in the string input at position position is a U+0020 SPACE, U+002C COMMA, or U+003B SEMICOLON character, then return to step 4.

  7. Let negated be false.

  8. Let value be 0.

  9. Let started be false. This variable is set to true when the parser sees a number or a U+002D HYPHEN-MINUS character (-).

  10. Let got number be false. This variable is set to true when the parser sees a number.

  11. Let finished be false. This variable is set to true to switch parser into a mode where it ignores characters until the next separator.

  12. Let bogus be false.

  13. Parser: If the character in the string input at position position is:

    A U+002D HYPHEN-MINUS character

    Follow these substeps:

    1. If got number is true, let finished be true.
    2. If finished is true, skip to the next step in the overall set of steps.
    3. If started is true, let negated be false.
    4. Otherwise, if started is false and if bogus is false, let negated be true.
    5. Let started be true.
    A character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9)

    Follow these substeps:

    1. If finished is true, skip to the next step in the overall set of steps.
    2. Multiply value by ten.
    3. Add the value of the digit, interpreted in base ten, to value.
    4. Let started be true.
    5. Let got number be true.
    A U+0020 SPACE character
    A U+002C COMMA character
    A U+003B SEMICOLON character

    Follow these substeps:

    1. If got number is false, return the numbers list and abort. This happens if an entry in the list has no digits, as in "1,2,x,4".
    2. If negated is true, then negate value.
    3. Append value to the numbers list.
    4. Jump to step 4 in the overall set of steps.
    A character in the range U+0001 to U+001F, U+0021 to U+002B, U+002D to U+002F, U+003A, U+003C to U+0040, U+005B to U+0060, U+007b to U+007F (i.e. any other non-alphabetic ASCII character)

    Follow these substeps:

    1. If got number is true, let finished be true.
    2. If finished is true, skip to the next step in the overall set of steps.
    3. Let negated be false.
    Any other character

    Follow these substeps:

    1. If finished is true, skip to the next step in the overall set of steps.
    2. Let negated be false.
    3. Let bogus be true.
    4. If started is true, then return the numbers list, and abort. (The value in value is not appended to the list first; it is dropped.)
  14. Advance position to the next character in input, or to beyond the end of the string if there are no more characters.

  15. If position points to a character (and not to beyond the end of input), jump to the big Parser step above.

  16. If negated is true, then negate value.

  17. If got number is true, then append value to the numbers list.

  18. Return the numbers list and abort.

2.5.4.6 Lists of dimensions

The rules for parsing a list of dimensions are as follows. These rules return a list of zero or more pairs consisting of a number and a unit, the unit being one of percentage, relative, and absolute.

  1. Let raw input be the string being parsed.

  2. If the last character in raw input is a U+002C COMMA character (,), then remove that character from raw input.

  3. Split the string raw input on commas. Let raw tokens be the resulting list of tokens.

  4. Let result be an empty list of number/unit pairs.

  5. For each token in raw tokens, run the following substeps:

    1. Let input be the token.

    2. Let position be a pointer into input, initially pointing at the start of the string.

    3. Let value be the number 0.

    4. Let unit be absolute.

    5. If position is past the end of input, set unit to relative and jump to the last substep.

    6. If the character at position is a character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), collect a sequence of characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), interpret the resulting sequence as an integer in base ten, and increment value by that integer.

    7. If the character at position is a U+002E FULL STOP character (.), run these substeps:

      1. Collect a sequence of characters consisting of space characters and characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). Let s be the resulting sequence.

      2. Remove all space characters in s.

      3. If s is not the empty string, run these subsubsteps:

        1. Let length be the number of characters in s (after the spaces were removed).

        2. Let fraction be the result of interpreting s as a base-ten integer, and then dividing that number by 10length.

        3. Increment value by fraction.

    8. Skip whitespace.

    9. If the character at position is a U+0025 PERCENT SIGN character (%), then set unit to percentage.

      Otherwise, if the character at position is a U+002A ASTERISK character (*), then set unit to relative.

    10. Add an entry to result consisting of the number given by value and the unit given by unit.

  6. Return the list result.

2.5.5 Dates and times

In the algorithms below, the number of days in month month of year year is: 31 if month is 1, 3, 5, 7, 8, 10, or 12; 30 if month is 4, 6, 9, or 11; 29 if month is 2 and year is a number divisible by 400, or if year is a number divisible by 4 but not by 100; and 28 otherwise. This takes into account leap years in the Gregorian calendar. [GREGORIAN]

The digits in the date and time syntaxes defined in this section must be characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), used to express numbers in base ten.

While the formats described here are intended to be subsets of the corresponding ISO8601 formats, this specification defines parsing rules in much more detail than ISO8601. Implementors are therefore encouraged to carefully examine any date parsing libraries before using them to implement the parsing rules described below; ISO8601 libraries might not parse dates and times in exactly the same manner. [ISO8601]

2.5.5.1 Months

A month consists of a specific proleptic Gregorian date with no time-zone information and no date information beyond a year and a month. [GREGORIAN]

A string is a valid month string representing a year year and month month if it consists of the following components in the given order:

  1. Four or more digits, representing year, where year > 0
  2. A U+002D HYPHEN-MINUS character (-)
  3. Two digits, representing the month month, in the range 1 ≤ month ≤ 12

The rules to parse a month string are as follows. This will return either a year and month, or nothing. If at any point the algorithm says that it "fails", this means that it is aborted at that point and returns nothing.

  1. Let input be the string being parsed.

  2. Let position be a pointer into input, initially pointing at the start of the string.

  3. Parse a month component to obtain year and month. If this returns nothing, then fail.

  4. If position is not beyond the end of input, then fail.

  5. Return year and month.

The rules to parse a month component, given an input string and a position, are as follows. This will return either a year and a month, or nothing. If at any point the algorithm says that it "fails", this means that it is aborted at that point and returns nothing.

  1. Collect a sequence of characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected sequence is not at least four characters long, then fail. Otherwise, interpret the resulting sequence as a base-ten integer. Let that number be the year.

  2. If year is not a number greater than zero, then fail.

  3. If position is beyond the end of input or if the character at position is not a U+002D HYPHEN-MINUS character, then fail. Otherwise, move position forwards one character.

  4. Collect a sequence of characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected sequence is not exactly two characters long, then fail. Otherwise, interpret the resulting sequence as a base-ten integer. Let that number be the month.

  5. If month is not a number in the range 1 ≤ month ≤ 12, then fail.

  6. Return year and month.

2.5.5.2 Dates

A date consists of a specific proleptic Gregorian date with no time-zone information, consisting of a year, a month, and a day. [GREGORIAN]

A string is a valid date string representing a year year, month month, and day day if it consists of the following components in the given order:

  1. A valid month string, representing year and month
  2. A U+002D HYPHEN-MINUS character (-)
  3. Two digits, representing day, in the range 1 ≤ day ≤ maxday where maxday is the number of days in the month month and year year

The rules to parse a date string are as follows. This will return either a date, or nothing. If at any point the algorithm says that it "fails", this means that it is aborted at that point and returns nothing.

  1. Let input be the string being parsed.

  2. Let position be a pointer into input, initially pointing at the start of the string.

  3. Parse a date component to obtain year, month, and day. If this returns nothing, then fail.

  4. If position is not beyond the end of input, then fail.

  5. Let date be the date with year year, month month, and day day.

  6. Return date.

The rules to parse a date component, given an input string and a position, are as follows. This will return either a year, a month, and a day, or nothing. If at any point the algorithm says that it "fails", this means that it is aborted at that point and returns nothing.

  1. Parse a month component to obtain year and month. If this returns nothing, then fail.

  2. Let maxday be the number of days in month month of year year.

  3. If position is beyond the end of input or if the character at position is not a U+002D HYPHEN-MINUS character, then fail. Otherwise, move position forwards one character.

  4. Collect a sequence of characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected sequence is not exactly two characters long, then fail. Otherwise, interpret the resulting sequence as a base-ten integer. Let that number be the day.

  5. If day is not a number in the range 1 ≤ day ≤ maxday, then fail.

  6. Return year, month, and day.

2.5.5.3 Times

A time consists of a specific time with no time-zone information, consisting of an hour, a minute, a second, and a fraction of a second.

A string is a valid time string representing an hour hour, a minute minute, and a second second if it consists of the following components in the given order:

  1. Two digits, representing hour, in the range 0 ≤ hour ≤ 23
  2. A U+003A COLON character (:)
  3. Two digits, representing minute, in the range 0 ≤ minute ≤ 59
  4. Optionally (required if second is non-zero):
    1. A U+003A COLON character (:)
    2. Two digits, representing the integer part of second, in the range 0 ≤ s ≤ 59
    3. Optionally (required if second is not an integer):
      1. A 002E FULL STOP character (.)
      2. One or more digits, representing the fractional part of second

The second component cannot be 60 or 61; leap seconds cannot be represented.

The rules to parse a time string are as follows. This will return either a time, or nothing. If at any point the algorithm says that it "fails", this means that it is aborted at that point and returns nothing.

  1. Let input be the string being parsed.

  2. Let position be a pointer into input, initially pointing at the start of the string.

  3. Parse a time component to obtain hour, minute, and second. If this returns nothing, then fail.

  4. If position is not beyond the end of input, then fail.

  5. Let time be the time with hour hour, minute minute, and second second.

  6. Return time.

The rules to parse a time component, given an input string and a position, are as follows. This will return either an hour, a minute, and a second, or nothing. If at any point the algorithm says that it "fails", this means that it is aborted at that point and returns nothing.

  1. Collect a sequence of characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected sequence is not exactly two characters long, then fail. Otherwise, interpret the resulting sequence as a base-ten integer. Let that number be the hour.

  2. If hour is not a number in the range 0 ≤ hour ≤ 23, then fail.
  3. If position is beyond the end of input or if the character at position is not a U+003A COLON character, then fail. Otherwise, move position forwards one character.

  4. Collect a sequence of characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected sequence is not exactly two characters long, then fail. Otherwise, interpret the resulting sequence as a base-ten integer. Let that number be the minute.

  5. If minute is not a number in the range 0 ≤ minute ≤ 59, then fail.
  6. Let second be a string with the value "0".

  7. If position is not beyond the end of input and the character at position is a U+003A COLON, then run these substeps:

    1. Advance position to the next character in input.

    2. If position is beyond the end of input, or at the last character in input, or if the next two characters in input starting at position are not two characters both in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then fail.

    3. Collect a sequence of characters that are either characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9) or U+002E FULL STOP characters. If the collected sequence has more than one U+002E FULL STOP characters, or if the last character in the sequence is a U+002E FULL STOP character, then fail. Otherwise, let the collected string be second instead of its previous value.

  8. Interpret second as a base-ten number (possibly with a fractional part). Let second be that number instead of the string version.

  9. If second is not a number in the range 0 ≤ second < 60, then fail.

  10. Return hour, minute, and second.

2.5.5.4 Local dates and times

A local date and time consists of a specific proleptic Gregorian date, consisting of a year, a month, and a day, and a time, consisting of an hour, a minute, a second, and a fraction of a second, but expressed without a time zone. [GREGORIAN]

A string is a valid local date and time string representing a date and time if it consists of the following components in the given order:

  1. A valid date string representing the date.
  2. A U+0054 LATIN CAPITAL LETTER T character (T).
  3. A valid time string representing the time.

The rules to parse a local date and time string are as follows. This will return either a date and time, or nothing. If at any point the algorithm says that it "fails", this means that it is aborted at that point and returns nothing.

  1. Let input be the string being parsed.

  2. Let position be a pointer into input, initially pointing at the start of the string.

  3. Parse a date component to obtain year, month, and day. If this returns nothing, then fail.

  4. If position is beyond the end of input or if the character at position is not a U+0054 LATIN CAPITAL LETTER T character (T) then fail. Otherwise, move position forwards one character.

  5. Parse a time component to obtain hour, minute, and second. If this returns nothing, then fail.

  6. If position is not beyond the end of input, then fail.

  7. Let date be the date with year year, month month, and day day.

  8. Let time be the time with hour hour, minute minute, and second second.

  9. Return date and time.

2.5.5.5 Global dates and times

A global date and time consists of a specific proleptic Gregorian date, consisting of a year, a month, and a day, and a time, consisting of an hour, a minute, a second, and a fraction of a second, expressed with a time-zone offset, consisting of a signed number of hours and minutes. [GREGORIAN]

A string is a valid global date and time string representing a date, time, and a time-zone offset if it consists of the following components in the given order:

  1. A valid date string representing the date
  2. A U+0054 LATIN CAPITAL LETTER T character (T)
  3. A valid time string representing the time
  4. Either:

This format allows for time-zone offsets from -23:59 to +23:59. In practice, however, the range of offsets of actual time zones is -12:00 to +14:00, and the minutes component of offsets of actual time zones is always either 00, 30, or 45.

Times in dates before the formation of UTC in the mid twentieth century must be expressed and interpreted in terms of UT1 (contemporary Earth solar time at the 0° longitude), not UTC (the approximation of UT1 that ticks in SI seconds). Time before the formation of time zones must be expressed and interpeted as UT1 times with explicit time zones that approximate the contemporary difference between the appropriate local time and the time observed at the location of Greenwich, London.

The following are some examples of dates written as valid global date and time strings.

"0037-12-13T00:00Z"
Midnight in areas using London time on the birthday of Nero (the Roman Emperor). See below for further discussion on which date this actually corresponds to.
"1979-10-14T12:00:00.001-04:00"
One millisecond after noon on October 14th 1979, in the time zone in use on the east coast of the USA during daylight saving time.
"8592-01-01T02:09+02:09"
Midnight UTC on the 1st of January, 8592. The time zone associated with that time is two hours and nine minutes ahead of UTC, which is not currently a real time zone, but is nonetheless allowed.

Several things are notable about these dates:

The best representation of the global date and time string datetime is the valid global date and time string representing datetime, with the valid time string component being given in its shortest possible form, with the last character of the string not being a U+005A LATIN CAPITAL LETTER Z character (Z), even if the time zone is UTC, and with a U+002B PLUS SIGN character (+) representing the sign of the time-zone offset when the time zone is UTC.

The rules to parse a global date and time string are as follows. This will return either a time in UTC, with associated time-zone offset information for round-tripping or display purposes, or nothing. If at any point the algorithm says that it "fails", this means that it is aborted at that point and returns nothing.

  1. Let input be the string being parsed.

  2. Let position be a pointer into input, initially pointing at the start of the string.

  3. Parse a date component to obtain year, month, and day. If this returns nothing, then fail.

  4. If position is beyond the end of input or if the character at position is not a U+0054 LATIN CAPITAL LETTER T character (T) then fail. Otherwise, move position forwards one character.

  5. Parse a time component to obtain hour, minute, and second. If this returns nothing, then fail.

  6. If position is beyond the end of input, then fail.

  7. Parse a time-zone offset component to obtain timezonehours and timezoneminutes. If this returns nothing, then fail.

  8. If position is not beyond the end of input, then fail.

  9. Let time be the moment in time at year year, month month, day day, hours hour, minute minute, second second, subtracting timezonehours hours and timezoneminutes minutes. That moment in time is a moment in the UTC time zone.

  10. Let timezone be timezonehours hours and timezoneminutes minutes from UTC.

  11. Return time and timezone.

The rules to parse a time-zone offset component, given an input string and a position, are as follows. This will return either time-zone hours and time-zone minutes, or nothing. If at any point the algorithm says that it "fails", this means that it is aborted at that point and returns nothing.

  1. If the character at position is a U+005A LATIN CAPITAL LETTER Z character (Z), then:

    1. Let timezonehours be 0.

    2. Let timezoneminutes be 0.

    3. Advance position to the next character in input.

    Otherwise, if the character at position is either a U+002B PLUS SIGN (+) or a U+002D HYPHEN-MINUS (-), then:

    1. If the character at position is a U+002B PLUS SIGN (+), let sign be "positive". Otherwise, it's a U+002D HYPHEN-MINUS (-); let sign be "negative".

    2. Advance position to the next character in input.

    3. Collect a sequence of characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected sequence is not exactly two characters long, then fail. Otherwise, interpret the resulting sequence as a base-ten integer. Let that number be the timezonehours.

    4. If timezonehours is not a number in the range 0 ≤ timezonehours ≤ 23, then fail.
    5. If sign is "negative", then negate timezonehours.
    6. If position is beyond the end of input or if the character at position is not a U+003A COLON character, then fail. Otherwise, move position forwards one character.

    7. Collect a sequence of characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected sequence is not exactly two characters long, then fail. Otherwise, interpret the resulting sequence as a base-ten integer. Let that number be the timezoneminutes.

    8. If timezoneminutes is not a number in the range 0 ≤ timezoneminutes ≤ 59, then fail.
    9. If sign is "negative", then negate timezoneminutes.

    Otherwise, fail.

  2. Return timezonehours and timezoneminutes.

2.5.5.6 Weeks

A week consists of a week-year number and a week number representing a seven-day period starting on a Monday. Each week-year in this calendaring system has either 52 or 53 such seven-day periods, as defined below. The seven-day period starting on the Gregorian date Monday December 29th 1969 (1969-12-29) is defined as week number 1 in week-year 1970. Consecutive weeks are numbered sequentially. The week before the number 1 week in a week-year is the last week in the previous week-year, and vice versa. [GREGORIAN]

A week-year with a number year has 53 weeks if it corresponds to either a year year in the proleptic Gregorian calendar that has a Thursday as its first day (January 1st), or a year year in the proleptic Gregorian calendar that has a Wednesday as its first day (January 1st) and where year is a number divisible by 400, or a number divisible by 4 but not by 100. All other week-years have 52 weeks.

The week number of the last day of a week-year with 53 weeks is 53; the week number of the last day of a week-year with 52 weeks is 52.

The week-year number of a particular day can be different than the number of the year that contains that day in the proleptic Gregorian calendar. The first week in a week-year y is the week that contains the first Thursday of the Gregorian year y.

A string is a valid week string representing a week-year year and week week if it consists of the following components in the given order:

  1. Four or more digits, representing year, where year > 0
  2. A U+002D HYPHEN-MINUS character (-)
  3. A U+0057 LATIN CAPITAL LETTER W character (W)
  4. Two digits, representing the week week, in the range 1 ≤ week ≤ maxweek, where maxweek is the week number of the last day of week-year year

The rules to parse a week string are as follows. This will return either a week-year number and week number, or nothing. If at any point the algorithm says that it "fails", this means that it is aborted at that point and returns nothing.

  1. Let input be the string being parsed.

  2. Let position be a pointer into input, initially pointing at the start of the string.

  3. Collect a sequence of characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected sequence is not at least four characters long, then fail. Otherwise, interpret the resulting sequence as a base-ten integer. Let that number be the year.

  4. If year is not a number greater than zero, then fail.

  5. If position is beyond the end of input or if the character at position is not a U+002D HYPHEN-MINUS character, then fail. Otherwise, move position forwards one character.

  6. If position is beyond the end of input or if the character at position is not a U+0057 LATIN CAPITAL LETTER W character (W), then fail. Otherwise, move position forwards one character.

  7. Collect a sequence of characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected sequence is not exactly two characters long, then fail. Otherwise, interpret the resulting sequence as a base-ten integer. Let that number be the week.

  8. Let maxweek be the week number of the last day of year year.

  9. If week is not a number in the range 1 ≤ week ≤ maxweek, then fail.

  10. If position is not beyond the end of input, then fail.

  11. Return the week-year number year and the week number week.

2.5.5.7 Vaguer moments in time

A string is a valid date or time string if it is also one of the following:

A string is a valid date or time string in content if it consists of zero or more White_Space characters, followed by a valid date or time string, followed by zero or more further White_Space characters.


A string is a valid date string with optional time if it is also one of the following:

A string is a valid date string in content with optional time if it consists of zero or more White_Space characters, followed by a valid date string with optional time, followed by zero or more further White_Space characters.


The rules to parse a date or time string are as follows. The algorithm is invoked with a flag indicating if the in attribute variant or the in content variant is to be used. The algorithm will return either a date, a time, a global date and time, or nothing. If at any point the algorithm says that it "fails", this means that it is aborted at that point and returns nothing.

  1. Let input be the string being parsed.

  2. Let position be a pointer into input, initially pointing at the start of the string.

  3. For the in content variant: skip White_Space characters.

  4. Set start position to the same position as position.

  5. Set the date present and time present flags to true.

  6. Parse a date component to obtain year, month, and day. If this fails, then set the date present flag to false.

  7. If date present is true, and position is not beyond the end of input, and the character at position is a U+0054 LATIN CAPITAL LETTER T character (T), then advance position to the next character in input.

    Otherwise, if date present is true, and either position is beyond the end of input or the character at position is not a U+0054 LATIN CAPITAL LETTER T character (T), then set time present to false.

    Otherwise, if date present is false, set position back to the same position as start position.

  8. If the time present flag is true, then parse a time component to obtain hour, minute, and second. If this returns nothing, then fail.

  9. If the date present and time present flags are both true, but position is beyond the end of input, then fail.

  10. If the date present and time present flags are both true, parse a time-zone offset component to obtain timezonehours and timezoneminutes. If this returns nothing, then fail.

  11. For the in content variant: skip White_Space characters.

  12. If position is not beyond the end of input, then fail.

  13. If the date present flag is true and the time present flag is false, then let date be the date with year year, month month, and day day, and return date.

    Otherwise, if the time present flag is true and the date present flag is false, then let time be the time with hour hour, minute minute, and second second, and return time.

    Otherwise, let time be the moment in time at year year, month month, day day, hours hour, minute minute, second second, subtracting timezonehours hours and timezoneminutes minutes, that moment in time being a moment in the UTC time zone; let timezone be timezonehours hours and timezoneminutes minutes from UTC; and return time and timezone.

2.5.6 Colors

A simple color consists of three 8-bit numbers in the range 0..255, representing the red, green, and blue components of the color respectively, in the sRGB color space. [SRGB]

A string is a valid simple color if it is exactly seven characters long, and the first character is a U+0023 NUMBER SIGN character (#), and the remaining six characters are all in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), U+0041 LATIN CAPITAL LETTER A to U+0046 LATIN CAPITAL LETTER F, U+0061 LATIN SMALL LETTER A to U+0066 LATIN SMALL LETTER F, with the first two digits representing the red component, the middle two digits representing the green component, and the last two digits representing the blue component, in hexadecimal.

A string is a valid lowercase simple color if it is a valid simple color and doesn't use any characters in the range U+0041 LATIN CAPITAL LETTER A to U+0046 LATIN CAPITAL LETTER F.

The rules for parsing simple color values are as given in the following algorithm. When invoked, the steps must be followed in the order given, aborting at the first step that returns a value. This algorithm will return either a simple color or an error.

  1. Let input be the string being parsed.

  2. If input is not exactly seven characters long, then return an error.

  3. If the first character in input is not a U+0023 NUMBER SIGN character (#), then return an error.

  4. If the last six characters of input are not all in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), U+0041 LATIN CAPITAL LETTER A to U+0046 LATIN CAPITAL LETTER F, U+0061 LATIN SMALL LETTER A to U+0066 LATIN SMALL LETTER F, then return an error.

  5. Let result be a simple color.

  6. Interpret the second and third characters as a hexadecimal number and let the result be the red component of result.

  7. Interpret the fourth and fifth characters as a hexadecimal number and let the result be the green component of result.

  8. Interpret the sixth and seventh characters as a hexadecimal number and let the result be the blue component of result.

  9. Return result.

The rules for serializing simple color values given a simple color are as given in the following algorithm:

  1. Let result be a string consisting of a single U+0023 NUMBER SIGN character (#).

  2. Convert the red, green, and blue components in turn to two-digit hexadecimal numbers using the digits U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9) and U+0061 LATIN SMALL LETTER A to U+0066 LATIN SMALL LETTER F, zero-padding if necessary, and append these numbers to result, in the order red, green, blue.

  3. Return result, which will be a valid lowercase simple color.


Some obsolete legacy attributes parse colors in a more complicated manner, using the rules for parsing a legacy color value, which are given in the following algorithm. When invoked, the steps must be followed in the order given, aborting at the first step that returns a value. This algorithm will return either a simple color or an error.

  1. Let input be the string being parsed.

  2. If input is the empty string, then return an error.

  3. Strip leading and trailing whitespace from input.

  4. If input is an ASCII case-insensitive match for the string "transparent", then return an error.

  5. If input is an ASCII case-insensitive match for one of the keywords listed in the SVG color keywords section of the CSS3 Color specification, then return the simple color corresponding to that keyword. [CSSCOLOR]

    CSS2 System Colors are not recognised.

  6. If input is four characters long, and the first character in input is a U+0023 NUMBER SIGN character (#), and the last three characters of input are all in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), U+0041 LATIN CAPITAL LETTER A to U+0046 LATIN CAPITAL LETTER F, and U+0061 LATIN SMALL LETTER A to U+0066 LATIN SMALL LETTER F, then run these substeps:

    1. Let result be a simple color.

    2. Interpret the second character of input as a hexadecimal digit; let the red component of result be the resulting number multiplied by 17.

    3. Interpret the third character of input as a hexadecimal digit; let the green component of result be the resulting number multiplied by 17.

    4. Interpret the fourth character of input as a hexadecimal digit; let the blue component of result be the resulting number multiplied by 17.

    5. Return result.

  7. Replace any characters in input that have a Unicode code point greater than U+FFFF (i.e. any characters that are not in the basic multilingual plane) with the two-character string "00".

  8. If input is longer than 128 characters, truncate input, leaving only the first 128 characters.

  9. If the first character in input is a U+0023 NUMBER SIGN character (#), remove it.

  10. Replace any character in input that is not in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), U+0041 LATIN CAPITAL LETTER A to U+0046 LATIN CAPITAL LETTER F, and U+0061 LATIN SMALL LETTER A to U+0066 LATIN SMALL LETTER F with the character U+0030 DIGIT ZERO (0).

  11. While input's length is zero or not a multiple of three, append a U+0030 DIGIT ZERO (0) character to input.

  12. Split input into three strings of equal length, to obtain three components. Let length be the length of those components (one third the length of input).

  13. If length is greater than 8, then remove the leading length-8 characters in each component, and let length be 8.

  14. While length is greater than two and the first character in each component is a U+0030 DIGIT ZERO (0) character, remove that character and reduce length by one.

  15. If length is still greater than two, truncate each component, leaving only the first two characters in each.

  16. Let result be a simple color.

  17. Interpret the first component as a hexadecimal number; let the red component of result be the resulting number.

  18. Interpret the second component as a hexadecimal number; let the green component of result be the resulting number.

  19. Interpret the third component as a hexadecimal number; let the blue component of result be the resulting number.

  20. Return result.


2.5.7 Space-separated tokens

A set of space-separated tokens is a string containing zero or more words (known as tokens) separated by one or more space characters, where words consist of any string of one or more characters, none of which are space characters.

A string containing a set of space-separated tokens may have leading or trailing space characters.

An unordered set of unique space-separated tokens is a set of space-separated tokens where none of the tokens are duplicated.

An ordered set of unique space-separated tokens is a set of space-separated tokens where none of the tokens are duplicated but where the order of the tokens is meaningful.

Sets of space-separated tokens sometimes have a defined set of allowed values. When a set of allowed values is defined, the tokens must all be from that list of allowed values; other values are non-conforming. If no such set of allowed values is provided, then all values are conforming.

How tokens in a set of space-separated tokens are to be compared (e.g. case-sensitively or not) is defined on a per-set basis.

When a user agent has to split a string on spaces, it must use the following algorithm:

  1. Let input be the string being parsed.

  2. Let position be a pointer into input, initially pointing at the start of the string.

  3. Let tokens be a list of tokens, initially empty.

  4. Skip whitespace

  5. While position is not past the end of input:

    1. Collect a sequence of characters that are not space characters.

    2. Add the string collected in the previous step to tokens.

    3. Skip whitespace

  6. Return tokens.

When a user agent has to remove a token from a string, it must use the following algorithm:

  1. Let input be the string being modified.

  2. Let token be the token being removed. It will not contain any space characters.

  3. Let output be the output string, initially empty.

  4. Let position be a pointer into input, initially pointing at the start of the string.

  5. Loop: If position is beyond the end of input, abort these steps.

  6. If the character at position is a space character:

    1. Append the character at position to the end of output.

    2. Advance position so it points at the next character in input.

    3. Return to the step labeled loop.

  7. Otherwise, the character at position is the first character of a token. Collect a sequence of characters that are not space characters, and let that be s.

  8. If s is exactly equal to token (this is a case-sensitive comparison), then:

    1. Skip whitespace (in input).

    2. Remove any space characters currently at the end of output.

    3. If position is not past the end of input, and output is not the empty string, append a single U+0020 SPACE character at the end of output.

  9. Otherwise, append s to the end of output.

  10. Return to the step labeled loop.

This causes any occurrences of the token to be removed from the string, and any spaces that were surrounding the token to be collapsed to a single space, except at the start and end of the string, where such spaces are removed.

2.5.8 Comma-separated tokens

A set of comma-separated tokens is a string containing zero or more tokens each separated from the next by a single U+002C COMMA character (,), where tokens consist of any string of zero or more characters, neither beginning nor ending with space characters, nor containing any U+002C COMMA characters (,), and optionally surrounded by space characters.

For instance, the string " a ,b,,d d " consists of four tokens: "a", "b", the empty string, and "d d". Leading and trailing whitespace around each token doesn't count as part of the token, and the empty string can be a token.

Sets of comma-separated tokens sometimes have further restrictions on what consists a valid token. When such restrictions are defined, the tokens must all fit within those restrictions; other values are non-conforming. If no such restrictions are specified, then all values are conforming.

When a user agent has to split a string on commas, it must use the following algorithm:

  1. Let input be the string being parsed.

  2. Let position be a pointer into input, initially pointing at the start of the string.

  3. Let tokens be a list of tokens, initially empty.

  4. Token: If position is past the end of input, jump to the last step.

  5. Collect a sequence of characters that are not U+002C COMMA characters (,). Let s be the resulting sequence (which might be the empty string).

  6. Remove any leading or trailing sequence of space characters from s.

  7. Add s to tokens.

  8. If position is not past the end of input, then the character at position is a U+002C COMMA character (,); advance position past that character.

  9. Jump back to the step labeled token.

  10. Return tokens.

2.5.9 References

A valid hash-name reference to an element of type type is a string consisting of a U+0023 NUMBER SIGN character (#) followed by a string which exactly matches the value of the name attribute of an element with type type in the document.

The rules for parsing a hash-name reference to an element of type type are as follows:

  1. If the string being parsed does not contain a U+0023 NUMBER SIGN character, or if the first such character in the string is the last character in the string, then return null and abort these steps.

  2. Let s be the string from the character immediately after the first U+0023 NUMBER SIGN character in the string being parsed up to the end of that string.

  3. Return the first element of type type that has an id attribute whose value is a case-sensitive match for s or a name attribute whose value is a compatibility caseless match for s.

2.5.10 Media queries

A string is a valid media query if it matches the media_query_list production of the Media Queries specification. [MQ]

A string matches the environment of the user if it is the empty string, a string consisting of only space characters, or is a media query that matches the user's environment according to the definitions given in the Media Queries specification. [MQ]