Web Fonts and providing fallback fonts

2019-03-29 06:10发布

问题:

When using web fonts using @font-face I was wondering what's the recommend method on using fallback fonts?

Like, for example if I was using a web font that was bold, such as:

@font-face {
    font-family: 'OpenSansBold';
    src: url('../fonts/OpenSans-Bold-webfont.eot');
    src: url('../fonts/OpenSans-Bold-webfont.eot?#iefix') format('embedded-opentype'),
         url('../fonts/OpenSans-Bold-webfont.woff') format('woff'),
         url('../fonts/OpenSans-Bold-webfont.ttf') format('truetype'),
         url('../fonts/OpenSans-Bold-webfont.svg#OpenSansBold') format('svg');
    font-weight: normal;
    font-style: normal;
}

Now when you call this you obviously just do this:

font-family: OpenSansBold;

However I was wondering about providing fallback fonts such as if the download of the font fails for whatever reason.

Obviously that's easy enough to do with a normal style font (non bold/non-italic) as below..

font-family: OpenSansRegular, Arial;

However, what I'm wondering is what about when the font is bold or italic.

Is it advised to something like this and it won't affect the web font?

font-family: OpenSansBold, Arial;
font-weight: bold;

Just wondering because if you didn't specify the bold then if the web font failed, they would get Arial, but it wouldn't be bold.

回答1:

You are presumably using font files and a CSS file as generated by FontSquirrel. The problem with their approach is that each specific font (such as Open Sans Regular and Open Sans Bold) is represented as a separate font-family, with font weight set to normal. This means that instead of markup like <p>foo <strong>bar</strong> and simple CSS like p { font-family: Open Sans, Arial } (letting browsers default strong to bold font weight and select the suitable font from the Open Sans family), you will be forced to set fonts explicitly. This means setting both font family and font weight, implicitly with the font-family property value.

You would need to tune the CSS to get a better approach. You would use the same font family but different weights in the @font-family rule, and in the font-family rule, you would only set the family:

@font-face {
    font-family: 'open_sans';
    src: url('opensans-bold-webfont.eot');
    src: url('opensans-bold-webfont.eot?#iefix') format('embedded-opentype'),
         url('opensans-bold-webfont.woff') format('woff'),
         url('opensans-bold-webfont.ttf') format('truetype'),
         url('opensans-bold-webfont.svg#OpenSans') format('svg');
    font-weight: bold;
    font-style: normal;
}   
@font-face {
    font-family: 'open_sans';
    src: url('opensans-regular-webfont.eot');
    src: url('opensans-regular-webfont.eot?#iefix') format('embedded-opentype'),
         url('opensans-regular-webfont.woff') format('woff'),
         url('opensans-regular-webfont.ttf') format('truetype'),
         url('opensans-regular-webfont.svg#OpenSans') format('svg');
    font-weight: normal;
    font-style: normal;
}
* { font-family: open_sans, Arial; }

And then you would just use font-weight: bold (or HTML markup that has such an effect by default, like strong, b, th, h1 through h6) for those elements that should appear in Open Sans Bold.

Doing it the way you describe appears to work on most browsers, too, but I wouldn’t count on it. Once you have declared a font as normal weight in your @font-face, setting font-weight: bold on text in that font could cause a) a failure, since a the weights don’t match or b) the font taken as a starting point for algorithmic bolding, resulting in double bolding. And if I’m not mistaken, b) is what happens on Safari (Win 7).



回答2:

You've correctly highlighted an issue with the 'new age' of web fonts, this blog post discusses it and presents a workaround http://elliotjaystocks.com/blog/font-weight-in-the-age-of-web-fonts/

Relevant snippet

Problem number two is significantly bigger than the first. Consider FF Enzo, which doesn’t have a 400 (or even 500) weight. In some circumstances, its Light (300) weight might perhaps be a little too thin for small body type, so let’s use the 600 weight instead. Ah, that looks okay.

But it’s not okay! Because if that font can’t be displayed and we fallback to something else, that fallback font will render at its 600 weight; in other words: bold.

A workaround?

There’s a way around this and it’s the method FontsLive use in the CSS they generate for their users: you declare each weight individually rather than the entire family. Their code looks a bit like this:

CSS code:

{ font-family: 'FamilyName Light', 'FallbackFamily', serif; font-weight: normal; }
{ font-family: 'FamilyName Medium', 'FallbackFamily', serif; font-weight: normal; }
{ font-family: 'FamilyName Bold', 'FallbackFamily', serif; font-weight: bold; }
{ font-family: 'FamilyName Black', 'FallbackFamily', serif; font-weight: bold; }

Update:

@font-face {
    font-family: 'OpenSansBold';
    src: url('../fonts/OpenSans-Bold-webfont.eot');
    src: url('../fonts/OpenSans-Bold-webfont.eot?#iefix') format('embedded-opentype'),
         url('../fonts/OpenSans-Bold-webfont.woff') format('woff'),
         url('../fonts/OpenSans-Bold-webfont.ttf') format('truetype'),
         url('../fonts/OpenSans-Bold-webfont.svg#OpenSansBold') format('svg');
    font-weight: bold;
    font-style: normal;
}

And then something like (as you suggested):

{ font-family: OpenSansBold, 'Arial'; font-weight: bold; }