Are the quotes in
font-family: 'Comic Sans MS' required, or not?
According to the the CSS validator, the quotes are supposed to be there in this case because the font family name contains spaces:
Family names containing whitespace should be quoted. If quoting is omitted, any whitespace characters before and after the name are ignored and any sequence of whitespace characters inside the name is converted to a single space.
However, this is an error in the CSS validator. The warning message suggests that all font family names containing whitespace should be quoted, which is simply not true.
font-family: Comic Sans MS (without quotes) is perfectly valid CSS that works the way you’d expect it to.
In reality, it’s a bit more complex. To grok the rules on font family names, we need to understand the difference between CSS strings and identifiers first.
Strings and identifiers
The spec says the following about strings:
Strings can either be written with double quotes or with single quotes.
Identifiers are defined as follows:
In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the characters
[a-zA-Z0-9]and ISO 10646 characters U+00A0 and higher, plus the hyphen (
-) and the underscore (
ISO 10646 defines the Universal Character Set, which correlates to the Unicode standard. Note that they’re actually talking about the hyphen-minus character — not the hyphen character, which is U+2010. The code point for hyphen-minus is U+002D, and for underscore (low line) it’s U+005F. The highest code point currently allowed by Unicode is U+10FFFF. So, any character matching the regular expression
[-_a-zA-Z0-9\u00A0-\u10FFFF] is allowed in an identifier.
The spec continues:
[Identifiers] cannot start with a digit, two hyphens, or a hyphen followed by a digit. Identifiers can also contain escaped characters and any ISO 10646 character as a numeric code […]. For instance, the identifier
B&W?may be written as
Translated into regex: any string that matches
^(-?\d|--) is not a valid CSS identifier.
Both the CSS 2.1 and CSS3 Fonts Module Level 3 specs say:
Font family names must either be given quoted as strings, or unquoted as a sequence of one or more identifiers. This means most punctuation characters and digits at the start of each token must be escaped in unquoted font family names.
Note: “a sequence of one or more identifiers” implies that multiple space-separated identifiers will form a single font family name. Therefore,
font-family: Comic Sans MS is valid, and equivalent to
font-family: 'Comic Sans MS'. The former consists of three space-separated identifiers, the latter is simply a string.
This is clarified a few paragraphs down in the spec:
If a sequence of identifiers is given as a font family name, the computed value is the name converted to a string by joining all the identifiers in the sequence by single spaces.
The aforementioned CSS validator warning describes what happens if leading or trailing whitespace is used around identifier sequences:
[A]ny whitespace characters before and after the name are ignored, and any sequence of whitespace characters inside the name is converted to a single space.
This is implied by the spec text, too: an unescaped whitespace character can never be part of an identifier, so it can never start a “sequence of identifiers”.
Generic family keywords
The spec defines the following generic family keywords:
monospace. These keywords can be used as a general fallback mechanism, in case the desired font choices are not available. Authors are encouraged to append a generic font family as a last alternative for improved robustness. As keywords, they must not be quoted.
In other words,
font-family: sans-serif means that a generic sans-serif font family will be used, while
font-family: 'sans-serif' (with quotes) refers to an actual font that goes by the name of
sans-serif. A very important difference!
Other keyword values
The same behavior applies to a few other keywords, too:
Font family names that happen to be the same as a keyword value (
cursive) must be quoted to prevent confusion with the keywords with the same names. The keywords
defaultare reserved for future use and must also be quoted when used as font names. User agents must not consider these keywords as matching the
Note that all keywords are case-insensitive. For example,
mOnOsPaCe all refer to the same keyword, and if you want to use a font with that exact family name rather than the default keyword value, you’ll need to quote it.
As long as the only disallowed characters in an otherwise valid identifier are single U+0020 space characters, and all space-separated parts are valid identifiers too, the identifier sequence can be used as an unquoted font family name (unless it’s a keyword, but there are no keywords with spaces in them).
If a font family name matches a keyword, it must be quoted to form a string.
If you want to use an invalid CSS identifier as (part of) a font family name, you’ll need to quote it to form a string instead; or you could just escape any special characters so it can remain an unquoted identifier.
Here are some example
/* Invalid because `/` is not allowed in an identifier: */
/* Valid — an escaped `/` symbol is allowed in an identifier: */
/* Invalid because a string cannot be combined with an identifier: */
font-family: 'Lucida' Grande;
/* Valid — it’s a single string: */
font-family: 'Lucida Grande';
/* Valid — it’s a space-separated sequence of two identifiers: */
font-family: Lucida Grande;
/* Valid — it’s still a space-separated sequence of two identifiers: */
font-family: Lucida Grande;
/* Invalid because `!` is not allowed in an identifier: */
/* Valid — it’s a string: */
/* Valid — an escaped `!` is allowed in an identifier: */
/* Invalid because an identifier cannot start with a digit: */
font-family: Hawaii 5-0;
/* Valid — it’s a string: */
font-family: 'Hawaii 5-0';
/* Valid — `\35 ` (including the space) is an escape sequence for `5`: */
font-family: Hawaii \35 -0;
/* Valid — `\ ` (including the space) is an escape sequence for ` `: */
font-family: Hawaii\ 5-0;
/* Invalid — `$` is not allowed in an identifier: */
/* Valid — an escaped `$` symbol is allowed in an identifier: */
/* Valid — `€` is allowed in an identifier: */
Bonus puzzle: Other than keywords, I can only think of one font family name that can’t be used without quotes — there is no way to escape it in an identifier. Do you know which one?
Font family name checker
I’ve made a tool that will tell you if a given input string can be used as an unquoted font family name or not. Check it out!
Thanks to Simon Pieters for encouraging me to write about this.