Web字体及提供回退字体

9
使用@font-face时加载web字体,我想知道在使用后备字体方面的推荐方法。 例如,如果我正在使用粗体的Web字体,应该怎样选择后备字体呢?
@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;
}

现在,当您调用此函数时,您显然只需要执行以下操作:
font-family: OpenSansBold;

然而,我在考虑提供备用字体,例如如果由于任何原因下载字体失败。

显然,对于普通样式的字体(非粗体/非斜体),可以轻松完成如下操作...

font-family: OpenSansRegular, Arial;

然而,我想知道的是如果字体加粗或斜体时会怎样。

是否建议像这样做,并且不会影响Web字体?

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

我有个疑问,如果您没有指定加粗字体,那么如果网络字体加载失败,用户会看到Arial字体,但它不会是加粗的。

3个回答

12
您可能正在使用FontSquirrel生成的字体文件和CSS文件。他们的方法存在问题,即每个特定的字体(例如Open Sans Regular和Open Sans Bold)都表示为单独的字体系列,其字重设置为正常。这意味着您将被迫明确设置字体,而不是像<p>foo <strong>bar</strong>和简单的CSS代码p { font-family: Open Sans, Arial },让浏览器默认将strong元素设置为粗体并从Open Sans字体系列中选择合适的字体。
要解决此问题,您需要微调CSS以获得更好的方法。在@font-family规则中,您可以使用相同的字体系列但不同的字重,在font-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; }

然后你只需要使用font-weight: bold(或默认具有这种效果的HTML标记,例如strongbthh1h6)来设置那些应该以Open Sans Bold显示的元素。

按照您描述的方式似乎在大多数浏览器上都可以工作,但我不会全盘信任。一旦您已将字体声明为普通粗细(weight),在该字体上设置font-weight: bold可能会导致a)失败,因为重量不匹配,或b)作为算法加粗的起点采用字体,导致双重加粗。如果我没有记错,这就是Safari(Win 7)发生的情况。


好的解释。然而,如果你在font-family中给它们都起相同的名字,CSS怎么知道该使用哪一个呢?难道不会使用最后一个吗?此外,有没有关于如何处理"SemiBold"之类的东西的提示? - Brett
CSS通过匹配元素设置的font-weight和在@font-face块中定义的font-weight来确定使用哪一个。对于Google Web字体,SemiBold通常对应于font-weight: 600;这些对应关系在字体描述中显示,例如http://www.google.com/webfonts#UsePlace:use/Collection:Open+Sans。 - Jukka K. Korpela
刚刚在测试这个,遇到了一些问题。我按照谷歌文档设置了粗体的 OpenSans 字体,并将其加粗至 font-weight: 700;,但加载页面后发现文字比以前更加粗了。不确定原因 - 有什么想法吗? - Brett
请忽略我上一条评论 - 我错误地将 ExtraBold 设置为 font-weight: 700; - Brett

8
你已经正确地指出了“网络字体新时代”的一个问题,这篇博客文章讨论了它并提供了一种解决方法。http://elliotjaystocks.com/blog/font-weight-in-the-age-of-web-fonts/ 相关摘录:
第二个问题比第一个问题要严重得多。考虑FF Enzo,它没有400(甚至没有500)的字重。在某些情况下,它的Light(300)字重可能对于小型正文来说略显单薄,因此我们可以使用600字重。嗯,看起来还不错。
但这并不是好的解决方案!因为如果该字体无法显示并且我们需要使用其他字体,则回退字体将以其600字重呈现;换句话说:加粗。
解决方法?
有一种方法可以避免这个问题,这是FontsLive在生成其用户CSS时使用的方法:您逐个声明每个字重而不是整个字体系列。他们的代码类似于这样:
CSS代码:
{ 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; }

更新:

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

然后就像你建议的那样,出现了以下内容:
{ font-family: OpenSansBold, 'Arial'; font-weight: bold; }

非常好的信息 - 谢谢。那么在我的情况下,我有点困惑我应该改变什么。 - Brett
那个最后的代码片段正是我所需要的。其他几篇关于同一主题的SO帖子都没有任何帮助。 - Choylton B. Higginbottom

1
虽然接受的答案有效,但如果您想提供一个真正准确的备用字体,您需要为每个备选字体定义单独的行高和字母间距。这样做的主要原因是谷歌最近引入了累积布局移位(CLS)得分,指示页面在加载时跳动的程度。
您可以通过在字体加载之前在body上放置CSS类来实现此目的,如果字体加载成功,则会将其删除。我通过在页面顶部包含以下内容来实现这一点:
<script>!function(d){if (d.fonts.ready){d.body.className="loading";d.fonts.ready.then(function(){d.body.className=""})}}(document)</script>

你的CSS大致会像这样:

h1,p {font-family: Open Sans, Arial}
h1.loading {font-family: Arial;line-height:16px}
p.loading {font-family: Arial;line-height:12px}

通过在检查器中添加和删除“loading”类,您可以使用CSS来使其停止跳动。通过这种方法,您可以可靠地将CLS降至零,以取悦Google神。我发现唯一的替代方法是使用字体加载程序库,这会导致加载时间受到惩罚。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接