css3缺陷-字体显示的使用

如果你对CSS已经有了一定的了解,也许你之前已经掌握了一些字体加载方法,你用过font-display吗?

font-display是CSS中新添加的属性,可以实现之前由第三方脚本实现的功能,类似于Font Loading API和Bram Stein的Font Face Observer。

如果这是您第一次接触此类知识,没关系,我们首先简要介绍一下浏览器加载字体的默认方式。

浏览器如何加载字体?

浏览器经常会出现一些超出我们预期的问题,字体加载就是其中之一。 大多数浏览器会在下载自定义字体之前隐藏文本。 这就是所谓的 FOIT(隐形文本闪光)。

虽然您今天在正常加载期间可能不会看到这些内容,但我们可以通过限制连接速率来观察浏览器的默认行为。 可以看到,大多数浏览器都会隐藏文本3秒,直到字体加载完毕。 其他浏览器(例如 Safari)将等待更长时间。 有些甚至从不显示文本。

css3缺陷

我们目前解决此类问题的方法是使用基于 JavaScript 的脚本(例如 Font Face Observer)来跟踪字体是否下载。 在字体下载之前,我们使用浏览器自带的字体来显示文本。 在检测到字体是通过 JavaScript 下载之前,我们将 CSS 类添加到文档中以应用自定义字体。 这个方法我们之前已经详细介绍过。 例如,如果你有一个段落需要使用Open Sans Regular,那么你需要通过以下方式实现:

p {
    font-family: "Arial", "Helvetica", sans-serif;
}

下载字体后,它会首先使用 Arial 或 Helvetica(取决于您的浏览器支持的字体)来显示文本。 当我们通过 JavaScript 检测到 Open Sans Regular 字体已下载时css3缺陷,我们将 fonts-loaded 添加到标签中,并编写 CSS 以使用 Open Sans 呈现段落:

.fonts-loaded p {
    font-family: "Open Sans Regular";
}

这种方法看似可行,但变得相当麻烦。 这就是字体显示的用武之地。

了解字体显示

font-display 是一个新的 CSS 属性,首先在 Chrome 49 中试验,现在 Opera 和 Opera for Android 也支持。 通过使用这个属性,我们可以看到如何用一行 CSS 代码来实现以前通过 JavaScript 脚本实现的功能。

我们在 @font-face 指令中使用 font-display 来加载自定义字体。 该属性可以添加以下值:

现在我们知道 font-display 可以设置什么,我们可以在 @font-face 规则中使用它。 以下是使用 swap 作为值的示例:

@font-face {
  font-family: "Open Sans Regular";
  font-weight: 400;
  font-style: normal;
  src: url("fonts/OpenSans-Regular-BasicLatin.woff2") format("woff2");
  font-display: swap;
}

在本例中,我们仅使用 WOFF2 文件来缩写字体。 另外css3缺陷,我们使用swap作为font-display的值,页面加载会如下图所示:

当我们使用JavaScript来控制字体加载时,我们希望确保文本最初默认可见,并且当下载自定义字体时,应用自定义字体来渲染文本。

备用文本是什么? 当您为元素指定字体系列时,可以指定由冒号分隔的字体范围。 如果自定义字体之后的这些字体都能被浏览器支持,那么这个字体就是备用字体:

css3缺陷

p {
    font-family: "Open Sans Regular", "Helvetica", "Arial", sans-serif;
}

在前面的示例中,自定义字体为 Open Sans Regular,系统字体为 Helvetica 和 Arial。 当我们将font-display的值设置为swap时,首先会使用系统字体来显示文本,当下载自定义字体时,自定义字体将替换系统字体。 当 font-display 设置为后备和可选时,在决定如何处理自定义字体时,显示的字体将取决于系统堆栈中作为后备字体的字体。

大多数时候你可以选择使用swap作为属性值

如果你不知道选择哪一个作为font-display的属性值,可以选择swap。 除了在自定义字体和内容可访问性之间提供最佳平衡之外,它还提供与使用 JavaScript 脚本相同的字体加载行为。 如果你有想要在页面上加载的字体,但最终无法加载它,那么你可以考虑使用fallback或Optional作为font-display的值。

如果不支持字体显示怎么办?

字体显示的唯一缺点是它尚未得到广泛支持。 在这些情况下,您有两种选择:

如果您决定选择第二个选项,那么您首先需要确定浏览器是否支持 font-display 属性。 幸运的是,这是一件很容易做到的事情:

css3缺陷

if ("fontDisplay" in document.body.style === false) {
    /* JavaScript font loading logic goes here. */
}

通过判断未来的反馈,我们可以决定我们应该做什么,是否应该使用第三方JavaScript脚本,例如Font Face Observer,或者使用Firefox、Chrome和Opera支持的字体加载API。

if ("fontDisplay" in document.body.style === false) {
  if("fonts" in document) {
      document.fonts.load("1em Open Sans Regular");
      document.fonts.ready.then(function(fontFaceSet){
          document.documentElement.className += " fonts-loaded";
      })
  }
}

这里我们使用字体加载API来为我们解决这个问题。 一旦API知道字体已加载,我们就可以将fonts-loaded类添加到标签中,然后我们可以通过编写CSS逐步应用自定义字体。

p {
    font-family: "Helvetica", "Arial", sans-serif;
}
.fonts-loaded p {
    font-family: "Open Sans Regular";
}

显然,我们很乐意使用一行 CSS 代码来解决我们的需求,但至少我们需要能够在需要时提供替代方案。 随着时间的推移,我们可以预期这些解决方案(例如字体加载 API)也将在其他浏览器中可用。

如果您使用第三方字体提供商怎么办?

css3缺陷

如果您使用第三方字体提供商(例如 Google Fonts 或 TypeKit),您的操作就会受到限制。 font-display 属性必须在 @font-face 指令中使用。 因为您无法控制第三方字体提供程序的 CSS 文件,所以您无法控制 font-display 属性,更不用说向它传递值了。

但随着时间的推移,这些供应商可能会更改其 CSS 文件以包含 font-display 属性,或允许其作为可配置选项。

简而言之,font-display 是一个非常流行的属性。 除了改进网页的风格之外,它还大大简化了 JavaScript 中冗余和混乱的任务。 如果您使用的是 Chrome,则可以启用实验性 Web 平台并自行尝试 font-display 属性。

本文根据@Jeremy Wagner 的“font-display for the Massese”翻译。 整个翻译包含了我们自己的理解和想法。 如果翻译的不好或者有错误的地方,请各位同仁不吝赐教。 如果要转载此译文,必须注明中文来源:。

若水

研究生,计算机科学专业。 一个喜欢读书写作、热爱后端、享受成长的男孩。 我最喜欢的一句话:死时安心,生时不沉默。