选择多语言网站字体的注意事项

Avatar of Omar Bourhaouta
Omar Bourhaouta

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

作为一名为全球客户工作的前端开发人员,我一直难以处理多语言网站,尤其是在同时使用从右到左 (RTL) 和从左到右 (LTR) 的情况下。也就是说,我在此过程中学到了一些东西,并将在这篇文章中分享一些技巧。

让我们使用阿拉伯语和英语,不仅因为阿拉伯语是我的母语,还因为它是在使用中的 RTL 的一个经典示例。

向网站添加 RTL 支持

但是在此之前,我们需要在我们的网站上添加对 RTL 语言的支持。我们可以通过两种方式来实现这一点,这两种方式都不是理想的。

不理想:为每个方向使用特定的字体

我们可以采取的第一种方法是依赖于任何给定元素上的方向 (dir) 属性(通常是 <html> 元素,因此它全局设置方向)

/* For LTR, use Roboto */
[dir=ltr] body {
  font-family: "Roboto", sans-serif;
}

/* For RTL, use Amiri */
[dir=rtl] body {
  font-family: "Amiri", sans-serif;
}


PostCSS-RTL 使为每个方向生成样式变得更加容易,但是这种方法的问题在于您只使用了一种字体,如果您在一个段落中有多种语言,则这不是理想的。

原因如下。您会发现多语言段落会弄乱 UI,因为阿拉伯语字形被赋予了与元素不匹配的默认字体。

在某些浏览器中,情况可能会更糟。

也不理想:使用支持两种语言的单个字体

第二个选项可能是使用 提供对两种方向支持的字体。但是,根据我的个人经验,仅对两种语言使用一种字体会限制创造力和使用每种方向的不同字体的自由。根据设计要求,它可能不会那么糟糕。但我确实参与过一些项目,在这些项目中,它会产生影响。

好的,那接下来呢?

我们需要一个更简单的解决方案。根据 MDN

字体选择不仅仅停留在用户系统上列表中的第一个字体。相反,字体选择是逐个字符进行的,因此,如果可用字体没有所需字符的字形,则会尝试后面的字体。

这意味着,我们仍然可以使用 font-family 属性,但在第一个字体没有字符的字形的情况下使用回退。这实际上解决了上述两个问题,一石二鸟!

body {
  font-family: 'Roboto', 'Amiri', 'Galada', sans-serif;
}

为什么这有效?

就像 flexbox 和 CSS 网格使 CSS 布局更加灵活一样,字体匹配算法使处理不同语言的内容变得更加容易。以下是 W3C 关于如何将字符与字体匹配 的说法

当文本包含组合标记等字符时,理想情况下,基本字符应使用与标记相同的字体呈现,这可以确保标记的正确放置。出于这个原因,集群的字体匹配算法比单独匹配单个字符的一般情况更专业。**对于包含变体选择器的序列(指示要用于给定字符的确切字形),用户代理始终尝试系统字体回退以找到合适的字形,然后再使用基本字符的默认字形。**

(我强调的部分)

字体是如何匹配的?规范概述了算法执行的步骤,我将在这里进行概括。

  • 浏览器查看文本集群并尝试将其与 CSS 中声明的字体列表进行匹配。
  • 如果它找到一个支持所有字符的字体,那就太好了!这就是使用的字体。
  • 如果浏览器找不到支持所有字符的字体,它会重新读取字体列表以找到一个支持未匹配字符的字体,并将其应用于这些特定字符。
  • 如果浏览器在列表中找不到既不匹配集群中的所有字符也不匹配单个字符的字体,那么它就会使用 默认系统字体 并检查它是否支持所有字符。
  • 如果默认系统字体匹配,那就太好了!这就是使用的字体。
  • 如果系统字体不起作用,那就是浏览器呈现损坏的字形的地方。

让我们谈谈性能

我们刚刚看到的序列可能会对网站的性能造成影响。想象一下浏览器必须遍历每个定义的回退、将特定字符与字形匹配以及根据它找到的内容下载字体文件。这可能会增加很多工作量,更不用说 FOUT 和其他渲染怪异现象了。

目标是让 字体匹配算法 决定要应用于每个文本的字体,而不是依赖于两种语言的一种字体或添加额外的 CSS 来处理不同的方向。如果永远不会将字体应用于任何内容(例如,特定页面为 RTL 并且碰巧没有任何 LTR 文本,反之亦然),则不会下载堆栈中未使用的字体。

要实现这一点,需要选择合适的多种语言字体。合适的多种语言字体是指在页面上预期使用的尽可能多的字符都有字形的字体。如果您无法找到支持所有字符的字体,则使用支持大多数字符的字体,然后回退到另一字体也是一种有效的方法。如果碰巧是默认系统字体,那也同样好,因为它减少了一个要下载的字体文件。


让 font-family 属性决定每个字形的字体(而不是为每个方向创建额外的 CSS 选择器)的好处在于,该行为已经存在,正如我们前面概述的那样——我们只需要利用它即可。