Mathias Bynens

Unquoted font family names in CSS

Published · tagged with CSS

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\xA0-\u{10FFFF}] 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 B\&W\? or B\26 W\3F .

Translated into regex: any string that matches ^(-?\d|--) is not a valid CSS identifier.

Whitespace

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: serif, sans-serif, cursive, fantasy, and 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 (inherit, serif, sans-serif, monospace, fantasy, and cursive) must be quoted to prevent confusion with the keywords with the same names. The keywords initial and default are reserved for future use and must also be quoted when used as font names. User agents must not consider these keywords as matching the <family-name> type.

Note that all keywords are case-insensitive. For example, Monospace, monospace, and 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.

Summary

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 that aren’t keywords, the identifier sequence can be used as an unquoted font family name.

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 font-family declarations:

/* Invalid because `/` is not allowed in an identifier: */
font-family: Red/Black;
/* Valid — an escaped `/` symbol is allowed in an identifier: */
font-family: Red\/Black;
/* 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: */
font-family: Ahem!;
/* Valid — it’s a string: */
font-family: 'Ahem!';
/* Valid — an escaped `!` is allowed in an identifier: */
font-family: Ahem\!;
/* 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: */
font-family: $42;
/* Valid — an escaped `$` symbol is allowed in an identifier: */
font-family: \$42;
/* Valid — `€` is allowed in an identifier: */
font-family: €42;

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!

Unquoted CSS font family name validator

Thanks to Simon Pieters for encouraging me to write about this.

Bonus fun fact: Avoid using font family names that consist of more than 32 characters (including any quotes used to wrap the string). When such a name is used, Internet Explorer ≤ 10 ignores the font stack altogether, and falls back to the last-resort font.

About me

Hi there! I’m Mathias. I work on Chrome DevTools and the V8 JavaScript engine at Google. HTML, CSS, JavaScript, Unicode, performance, and security get me excited. Follow me on Twitter, Mastodon, and GitHub.

Comments

riddle wrote on :

Interesting study, thanks. I always quote font names because otherwise I would feel like I was introducing keywords into my stylesheet. The way I see it, font names are pieces of text, strings so in this case aesthetics wins with brevity.

Floris wrote on :

Sorry, I’d use double quotes rather than single quotes btw. If not only because it’s consistent with what I have always done.

JDJ wrote on :

Actually, as I read it, the CSS validator recommendation quoted at the top of the article doesn’t say that quotes are required. It simply says that they “should be quoted”.

The reasoning is weak, however. It basically warns that if any font families are used where the name legitimately has leading or trailing whitespace (e.g., ' TheFinalFrontier'), or has multiple consecutive whitespace characters inside them (e.g., 'Triple Space'), the CSS interpreter will not read them correctly without the quotes. Whitespace in the CSS value will be trimmed to remove leading and trailing spaces and consecutive spaces.

It is not likely that leading, trailing, or multiple whitespace characters will ever be used in a font family, though, so the recommendation is pretty silly.

— Random Reader

wrote on :

JDJ: You’re right! Your comment pretty much echoes my old comment on the CSS Validator bug ticket.

The thing is though, the CSS validator will show a warning for every unquoted font family name that contains whitespace, even for those that are simply space-separated identifiers, in which case the whitespace is completely harmless. This at least gives the impression that quotes are required, IMHO.

Dustin wrote on :

You prove the existence of Comic Sans to be natural in the browser, yet you refuse to use Comic Sans in the article that proves it. Well played…

fjpoblam wrote on :

Yep, it’s a bug in the CSS validator. But I always add the quotes simply to avoid the annoyance of extra messages from the validator. It’s a harmless accomodation on my part, and I use so few instances of quoted font-names in my CSS, I don’t feel the extra effort on my part, or the extra bandwidth during transmission of the CSS, are issues. Not really worth the fight for now. Non-issue.

Trevor wrote on :

The main concern I have which is not seemingly addressed here, is how to use multiple font names in a cascading order, where one or more names has a space, such as: News Gothic, Verdana, Arial ?

If the whole string is in quotes, like font-family: 'News Gothic, Verdana, Arial' does that then work,,,or what to do in this case....many people use fonts and then backup fonts, in a list like this....

thanks!

Jens wrote on :

What if a font family name contains a keyword but is not identical to a keyword as a sequence? E.g.:

font-family: herdo serif;

As far as I understand and according to your summary, it should be possible to use this font family unquoted. But according to your Font family name checker it must be quoted.

What is correct?

Thanks!

Leave a comment

Comment on “Unquoted font family names in CSS”

Your input will be parsed as Markdown.