Change fallback font for font-display:swap - css

As far as i am aware if you use the option "swap" for the property "font-display", Apple Mac uses Helvetica as fallback font and Windows Arial. Is it possible to define my own web-safe font like "Tahoma"?
Example code:
#font-face {
font-family: 'MyFancyFont';
src: local('MyFancyFont'), url(/fonts/MyFancyFont/MyFancyFont.woff2) format('woff2');
font-display: swap;
UseMyCustomFallbackFont: Tahoma
}

I believe this is done in the font-family definition, not the #font-face itself.
ex.
.my-text{
font-family: MyFancyFont, Tahoma;
}
This will show Tahoma until MyFancyFont is loaded.
You can get even more specific control if you use something like Webfont loader.
https://github.com/typekit/webfontloader

Related

Can I customise a #font-face declaration from an external imported CSS from a service like Adobe Fonts?

It's reasonably common for sites I'm building to use the semibold weight of a given font for their "bold" variant. Usually, this is very easy to set up by using a custom #font-face declaration that points at the semibold files and has font-weight: 700;.
That's fine when the fonts are available under a free licence, and can be hosted directly alongside the website. Sometimes, however, the fonts I need to use are only available under a paid licence. My employer pays for a subscription to Adobe Fonts to give us access to these fonts.
However, Adobe Fonts sets up its own #font-face declarations in the CSS files it provides for a given web project, and for semibold weights it uses the standard font-weight: 600;.
Unfortunately I've found very little information online about using #font-face with Adobe Fonts (or Typekit, which it used to be called). The closest thing I found on Adobe's own website (https://www.adobe.com/devnet/edge-web-fonts/articles/use-at-font-face-with-with-font-services.html) doesn't say anything about using #font-face with Adobe Fonts/Typekit.
I don't trust the file URLs Adobe Fonts uses in its CSS to remain static, so I don't think I can reuse them in my own CSS without risking breaking the fonts once those URLs are no longer correct.
Is there any way in CSS I can do something like create a new #font-face declaration based on a previous one created in an imported CSS file, or modify a #font-face declaration that was included this way? I'd much rather just set up the font to use its semibold files when the browser thinks it should be bold, instead of telling the browser to use the semibold font-weight where it would would normally use bold.
For anyone else running into this issue, the solution I've gone with for now is to create my own #font-face declaration using the URLs from Adobe Fonts' CSS file, but with a different name for the font family.
I'm using the Adobe Fonts font family as a fallback for if the one I've created doesn't load, so if the URLs break it should at least fall back to the one Adobe Fonts has set up with the font weights that don't match what I need.
/* Here Adobe Fonts uses #font-face to create the font family "adobe-font" */
#import "https://use.typekit.net/<my-project-key>.css";
#font-face {
font-family: "Custom Font";
src: url("https://use.typekit.net/path/to/font/file/regular.woff2") format("woff2"),
url("https://use.typekit.net/path/to/font/file/regular.woff") format("woff"),
url("https://use.typekit.net/path/to/font/file/regular.ott") format("opentype");
font-weight: 400;
font-style: normal;
font-display: auto;
}
#font-face {
font-family: "Custom Font";
src: url("https://use.typekit.net/path/to/font/file/italic.woff2") format("woff2"),
url("https://use.typekit.net/path/to/font/file/italic.woff") format("woff"),
url("https://use.typekit.net/path/to/font/file/italic.ott") format("opentype");
font-weight: 400;
font-style: italic;
font-display: auto;
}
#font-face {
font-family: "Custom Font";
src: url("https://use.typekit.net/path/to/font/file/semibold.woff2") format("woff2"),
url("https://use.typekit.net/path/to/font/file/semibold.woff") format("woff"),
url("https://use.typekit.net/path/to/font/file/semibold.ott") format("opentype");
font-weight: 700;
font-style: normal;
font-display: auto;
}
#font-face {
font-family: "Custom Font";
src: url("https://use.typekit.net/path/to/font/file/semibold-italic.woff2") format("woff2"),
url("https://use.typekit.net/path/to/font/file/semibold-italic.woff") format("woff"),
url("https://use.typekit.net/path/to/font/file/semibold-italic.ott") format("opentype");
font-weight: 700;
font-style: italic;
font-display: auto;
}
.my-class {
font-family: "Custom Font", "adobe-font", sans-serif;
}
It's not perfect, but since I haven't been able to find any assurance from Adobe that their font file URLs will never change this at least gives me some security if they do change.

Using the correct local font name

As a small optimisation technique I want to serve the 'Avenir Next - Regular' font locally via css (so if a user has this font locally it will use it rather than download a woff2/woff/etc).
This font, for example, has been in IOS since version 6 so it's a quick win.
However I am not sure how to specify the local font name in the css stack? Do I need the word regular? Is there a program that would help?
#font-face {
font-family: 'Avenir';
src: local("Avenir Next Regular"), /* THIS? */
local("Avenir-Next-Regular"), /* THIS? */
local("Avenir-Next"), /* SOMETHING ELSE? */
url('/fonts/AvenirNextLTW04Regular.woff2') format('woff2'),
url('/fonts/AvenirNextLTW04Regular.woff') format('woff'),
url('/fonts/AvenirNextLTW04Regular.ttf') format('truetype');
}
Do I need to specify a font weight to get the 'regular' version? And then is there a way in devtools to see if it works? I presume not seeing a call to an external font file means success?
You should use the correct font name as defined in the font file. If you are on Windows you can install Microsoft's Font properties extension. When installed, you just right click the font file and select Properties. There you will find extra tabs with the font's info. One of them will show the fonts name.
I guess it will be like this:
#font-face {
font-family: 'Avenir Next - Regular';
src: local('Avenir Next'),
url('/fonts/AvenirNextLTW04Regular.woff2') format('woff2'),
url('/fonts/AvenirNextLTW04Regular.woff') format('woff'),
url('/fonts/AvenirNextLTW04Regular.ttf') format('truetype');
}
The font family reflects the base name of a font, while the variants are the children (font faces) and are defined by weight (e.g. Regular, Bold) and style (normal & italic).
When defining custom #font-faces, make sure to define a common font-family, so that font-weight and font-style gets applied properly and the font-face switches accordingly within the same font family.
There is no official naming convention for the various font faces themselves, but most fonts do follow this this pattern:
[Font Name] [Weight?] [Italic?]
The names for the common weights are usually Thin, ExtraLight, Light, Regular, Medium, SemiBold, Bold, ExtraBold and Black.
However, some fonts may introduce an extra space in the Extra-variants or substitute Semi with Demi. More about the possible names can be found here.
Minor common exception: For the default 400-weight font, the name usually is Font Name Regular, while the weight is left out of the italic variant: Font Name Italic
Here is a table of possible font names for the imaginary font family Cool Font:
Weight
Style
Likely name
100
normal
Cool Font Thin
200
normal
Cool Font ExtraLight
300
normal
Cool Font Light
400
normal
Cool Font Regular
500
normal
Cool Font Medium
600
normal
Cool Font SemiBold
700
normal
Cool Font Bold
800
normal
Cool Font ExtraBold
900
normal
Cool Font Black
100
italic
Cool Font Thin Italic
200
italic
Cool Font ExtraLight Italic
300
italic
Cool Font Light Italic
400
italic
Cool Font Italic
500
italic
Cool Font Medium Italic
600
italic
Cool Font SemiBold Italic
700
italic
Cool Font Bold Italic
800
italic
Cool Font ExtraBold Italic
900
italic
Cool Font Black Italic
Keep in mind, that your font family might diverge from this table, so it is always best to check the font itself.
Example:
Assuming the entire family of Cool Font consists of an (italic) Regular and Bold font face sharing the naming convention described above, the correct definition could be:
#font-face {
font-family: 'Cool Font';
src: local('Cool Font Regular'),
url('Cool_Font_Regular.woff2') format('woff2'),
url('Cool_Font_Regular.woff') format('woff');
font-weight: 400;
font-style: normal;
}
#font-face {
font-family: 'Cool Font';
src: local('Cool Font Bold'),
url('Cool_Font_Bold.woff2') format('woff2'),
url('Cool_Font_Bold.woff') format('woff');
font-weight: 700;
font-style: normal;
}
#font-face {
font-family: 'Cool Font';
src: local('Cool Font Italic'),
url('Cool_Font_Italic.woff2') format('woff2'),
url('Cool_Font_Italic.woff') format('woff');
font-weight: 400;
font-style: italic;
}
#font-face {
font-family: 'Cool Font';
src: local('Cool Font Bold Italic'),
url('Cool_Font_Bold_Italic.woff2') format('woff2'),
url('Cool_Font_Bold_Italic.woff') format('woff');
font-weight: 700;
font-style: italic;
}
If you don't know the correct variant name of a font, you can always define multiple local variants without any downsides:
#font-face {
font-family: 'Cool Font';
src: local('Cool Font SemiBold'),
local('Cool Font Semi Bold'),
local('Cool Font DemiBold'),
local('Cool Font Demi Bold'),
url('Cool_Font_SemiBold.woff2') format('woff2'),
url('Cool_Font_SemiBold.woff') format('woff');
font-weight: 600;
font-style: normal;
}
When you don't want to let the user download a font and let it use the 'Avenir Next - Regular' font, you should put this font first in line in the font-declaration. Look into your own fonts for the exact name and set (only):
font-family: "Avenir Next - Regular", Arial, Helvetica, "sans-serif";
But check if 'Avenir Next - Regular' is so widely local available (not likely, because it is an expensive font).

Adding fallback fonts to the #font-face definition

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!
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;
}
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;
}
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;
}

font-face for local fonts

I have a framework of html/css pages using a font-face declaration with a otf. Now I want to switch it to a common font like Verdana. How can I assign Verdana to the font-face declaration avoiding a numerous replacement of font-family declaration? In other words: How can I use the font name declarated by font-face as a font variable?
#font-face {
font-family: 'bauer-bodoni.otf';
src: url(../fonts);
Should be something like this (which is not working in this form):
#font-face {
font-family: 'Verdana', 'Arial', sans-serif;
Thank you very much in advance.
-R.
EDIT/ANSWER: I've found out on my own. The trick is not to list the fonts the way you do in a normal font declaration, separated by comma, but with a "local()" for each:
#font-face {
font-family: 'myOwnFontSet';
src: local('Verdana');
src: local('Arial');
src: local(sans-serif);
Your update is still wrong. You need the following:
#font-face {
font-family: 'myOwnFontSet';
src: local('Verdana'), local('Arial'), local(sans-serif); }

Why not define font-weight or font-style in #font-face, Font Squirrel?

When we define #font-face styles, we can define whether the referenced files are for the bold, italic, or bold italic versions of a font, as discussed in this SO question:
How to add multiple font files for the same font?
Example:
#font-face {
font-family: 'FontinSans';
src: local('☺'), url('fontin_sans_regular.woff') format('woff');
font-weight: normal;
font-style: normal;
}
#font-face {
font-family: 'FontinSans';
src: local('☺'), url('fontin_sans_bold.woff') format('woff');
font-weight: bold;
font-style: normal;
}
However, Font Squirrel doesn't generate #font-face kits this way. They do something like this instead:
#font-face {
font-family: 'FontinSans';
src: local('☺'), url('fontin_sans_regular.woff') format('woff');
font-weight: normal;
font-style: normal;
}
#font-face {
font-family: 'FontinSansBold';
src: local('☺'), url('fontin_sans_bold.woff') format('woff');
font-weight: normal;
font-style: normal;
}
Which means in our CSS files we have to do things like this:
h2 {
font-family: 'FontinSansBold', Verdana, sans-serif;
font-weight: normal;
}
Why doesn't Font Squirrel use the font-weight and font-style declarations to distinguish the bold and italic variants? Why use a separate font family? Do they know something about (lack of) support for this feature in some browser?
By default, Font-Squirrel does this in order to increase support with user-agents that do not follow specification (those that ignore font-weight and font-style).
If you do not care about those outdated user-agents, you may enable the "Style Linking" option which is available in the expert section of the #font-face kit generator. Note that IE8 and below ignores numbered font-weight values and only support normal and bold (and corresponding 400, 700 weight values).
It does involve poking around inside the font to determine when a font is bold or italic. And certain bits must be set inside the font in order for IE to pick up the style linking. Most bold / italic fonts have these bits set, but not all. We are working on a way to make this more automatic.
It seems Internet Explorer 8 may be one of those "older" user agents that doesn't support font-weight and font-style
I am trying to make bold/italic/bolditalic automatic using the #font-face and font-family.
My attempts so far have yielded nothing. Here is a page demonstrating the problem.
http://clearimageonline.com/apps/playground/fonts/test_IE.html
Anyone here encountered this and have a solution that works with IE8?
I have searched and fiddled most of this week for an answer to this. It appears that IE8 wont let me do this.
Here is a proposed workaround (very ugly workaround)....
http://clearimageonline.com/apps/playground/fonts/proposed_IE.html
These test pages are designed for Internet Explorer ONLY. This test is limited to IE. Cross Browser functionality will obviouosly be a part of a final solution.
The problem using the default FontSquirrel's approach is that if the fallback font loads, all weights will be lost because they are all set to normal. I think the style linking is the best approach.
If you are worried about IE8 users you can use a conditional css.

Resources