网页中如何正确处理 CJK 字体

数字世界中的 CJK 字体 中,我介绍了 CJK 汉字的编码,不同地区的书写风格和字体差异,并介绍了如何正确渲染 CJK 汉字。

总结来说,因为 Unicode 对汉字进行了统一编码,而在不同地区,同一个汉字的书写风格、字形可能会有所不同,因此需要通过 声明内容的语言

指定内容的字体 来保证一段包含汉字的内容被正确渲染。

在网页中,以上两点,可以通过 HTML 中的 lang 属性和 CSS 中的 font-family 属性来实现。

方法1: 规范使用 HTML 的 lang 属性

使用 lang 属性指定网页或特定内容的语言,例如:

<html lang="zh-CN">(简体中文(中国))
<html lang="ja">(日文)。

系统会根据 lang 属性来选择合适的字体,主流操作系统均对 lang 属性有良好的支持。通常情况下,声明了 lang 属性,汉字都能被正确的系统默认字体渲染,会获得正确的地区字形。

方法2: 正确设置 CSS 的 font-family 属性

通常情况下,若网页并不需要使用特殊字体,设置 lang 属性已足够。
若网页有自定义字体的需求,可以与 方法1 配合使用 font-family 属性,这也是 Apple 官网的做法。

Apple 官网的做法

以下是不同地区 Apple 官网的 subhead 类的字体设置:

中国大陆:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-CN" lang="zh-CN" ...>
.subhead:lang(zh-CN) {
  font-family: "SF Pro SC", "SF Pro Display", "SF Pro Icons", "PingFang SC", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
}

日本:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja" ...>
.subhead:lang(ja) {
  font-family: "SF Pro JP", "SF Pro Display", "SF Pro Icons", "Hiragino Kaku Gothic Pro", "ヒラギノ角ゴ Pro W3", メイリオ, Meiryo, "MS Pゴシック", "Helvetica Neue", Helvetica, Arial, sans-serif;
}

香港:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-HK" lang="zh-HK" ...>
.subhead:lang(zh-HK) {
  font-family: "SF Pro HK", "SF Pro Display", "SF Pro Icons", "PingFang HK", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
}

台湾:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-TW" lang="zh-TW" ...>
.subhead:lang(zh-TW) {
  font-family: "SF Pro TC", "SF Pro Display", "SF Pro Icons", "PingFang TC", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
}

可以看到除了声明了 lang 属性,Apple 官网还针对不同的 lang 属性指定了不同的字体:

  • 中国大陆: SF Pro SCPingFang SC (后备字体)
  • 香港: SF Pro HKPingFang HK (后备字体)
  • 台湾: SF Pro TCPingFang TC (后备字体)
  • 日本: SF Pro JPHiragino Kaku Gothic Pro (后备字体)

了解 SF Pro CJK 字体

从 Apple 官网的 SF Pro 系列字体的 CSS 文件中可以看到,目前 SF Pro SC、SF Pro TC、SF Pro HK 指向的均为 PingFang 系列字体。 SF Pro JP 与 PingFang 无关,是 San Francisco + 微调版 AXIS 的组合字体来源,目前只用于 Apple 网页中。

SF Pro SC CSS
SF Pro JP CSS
SF Pro HK CSS
SF Pro TC CSS

CJK 网页中的 font-family 最佳实践

  1. 完整版(字体不与系统一致)

    ✅ 声明 lang 属性
    font-family 公式:   西文字体(例如 Inter) + CJK 地区字体(例如 PingFang TCNoto Sans TC) + 系统默认字体(system-ui, sans-serif) + Emoji 字体('Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol')
    此时西文文字可以被西文字体优先渲染,CJK 汉字被正确的地区字体渲染,其他文字使用系统默认字体渲染。

  2. 精简版(不需要个性化字体,保持跟系统一致)

    ✅ 声明 lang 属性
    font-family:   系统默认字体(system-ui, sans-serif)
    此时文字会被系统以在lang 属性声明的语言的字体渲染。

  3. 兼容版(保持跟系统一致,兼容老版本 Windows)

    ✅ 声明 lang 属性
    font-family:  -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"
    此时文字会被系统以在lang 属性声明的语言的字体渲染。

推荐文章

Playground

使用对应语言的 Noto Sans CJK 字体 (加载中...)
使用系统字体栈
使用单一字体
此时, 浏览器知道汉字所属的语言使用系统字体栈进行渲染。
系统若安装了对应语言的字体,则预期可以正常渲染,否则可能会出现字体混淆。
zh_Hans
zh_Hant
ja
ko

注意观察以上汉字在不同语言环境下的字形差异

参考: Han unification examples

lang 属性与 Noto Sans 字体的对应关系:ja 对应 Noto Sans JP,ko 对应 Noto Sans KR,zh_Hans 对应 Noto Sans SC,zh_Hant 对应 Noto Sans TC。