Adding fallback fonts to the @font-face definition

12.6k views Asked by At

Is it possible to add a fallback font directly to the definition of the font-face?

Example:

@font-face {
  font-family: 'MyWebFont', Arial, Helvetica, sans-serif;
  src: url('fonts/MyWebFont.eot');
  src: url('fonts/MyWebFont.eot?#iefix') format('embedded-opentype'),
  url('fonts/MyWebFont.woff') format('woff');
  font-weight: normal;
  font-style: normal;
}

And then using it as font-family value with automatic fallback, like so:

p {
  font-family: MyWebFont;
}

My goal is not to having to define the fallback fonts everywhere I define a new font-family. If not like above, can I somehow achieve this without JavaScript? Thanks for your help!

3

There are 3 answers

0
Jukka K. Korpela On BEST ANSWER

No, you cannot specify any fallback fonts inside a @font-face rule, because such a rule defines a font face and assigns a name to it. Inside the rule, the font-family part can contain only one name, the name you choose to assign. It would be pointless list several names there, since only the first one can possibly matter (and, besides, in this context no name has any predefined meaning, e.g. Arial would not mean the Arial font but be just an arbitrary assigned name).

Fallback fonts can be specified only in normal font-family rules.

Consider organizing your style sheet so that the relevant font-family list appears only once, using a suitable list of selectors, like

p, blockquote, .foobar, .something {
   font-family: MyWebFont, Arial, Helvetica, sans-serif;
}
1
GeekyMonkey On

CSS Variables is one solution to stay DRY

:root {
     --MainFont: "Gotham", "Franklin Gothic Medium", "Arial Narrow", Arial, sans-serif;
     --HeavyFont: "Gotham Black", "Franklin Gothic Medium", "Arial Narrow", Arial, sans-serif;
}

body {
     font-family: $MainFont;
}
h1 {
    font-family: $HeavyFont;
}
2
Kal On

You can totally add fallback fonts to a @font-face rule!* You don't add them to the font-family descriptor (that's for giving your font family a name); you add them to the src descriptor, which accepts multiple values. If the browser can't find (or doesn't support) the first font, it will try loading the next one, and so on. You can have it look for fonts installed on the user's system using the local() function:

@font-face {
  font-family: bodytext;
  src: url(fonts/MyWebFont.woff) format("woff"),
       local(Arial),
       local(Helvetica);
}

Some people may argue that url() and local() weren't designed to be used this way. Typically, they're used to provide local and remote versions of the same font, with the web-font functioning as a fallback if the local font can't be found. Here's such an example from the W3C specs:

@font-face {
  font-family: MyGentium;
  src: local(Gentium),    /* use locally available Gentium */
       url(Gentium.woff); /* otherwise, download it */
}

But there's nothing to say you can't use it in place of a regular font stack. Check out this W3C example:

Create an alias for local Japanese fonts on different platforms:

@font-face {
  font-family: jpgothic;
  src: local(HiraKakuPro-W3), local(Meiryo), local(IPAPGothic);
}

*There are some caveats though. Don't expect this to work exactly like the familiar font-family stack that you're used to. Firstly, there's no fallback for individual characters that may not be supported by your font. Secondly, you can't refer to generic font-families (like sans-serif, system-ui, etc). For those features, you're stuck with the classic font stack. But you can happily use both features, encapsulating all your named fonts in the @font-face rule, and adding the generic font as your last-resort fallback in the font-family declaration:

p {
  font-family: bodytext, sans-serif;
}