跳转至

关于 Mkdocs Metrial 自定义字体渲染和优化

1117 个字 47 行代码 2 张图片 预计阅读时间 4 分钟

这个网站讲了自定义字体使用的一种方式,这个网站讲的更加详细,介绍了多种方法。

但如果你想要用的字体不是 Google Fonts 上有的,手头只有.ttf或者.otf格式的文件,或者你想要更好的字体渲染效果,可以参考下面的做法。

准备自定义字体

本网站在普通文本中使用的中英文字体均为方正兰亭圆 GBK,有纤、细、准、中、中粗、粗、大、特8 个字重,由方正字库提供,模仿了游戏 Blue Archive 的字体风格;在 inner 代码块内使用英文字体为Ubuntu Mono derivative Powerline,中文字体默认;在代码块内使用的中文字体为方正兰亭圆 GBK,英文字体为Ubuntu Mono derivative Powerline

方正兰亭圆字体文件和FZLanT.font.css一同保存在我自己的阿里云 OSS 中,使用时仅需调取该 css 文件即可;Ubuntu Mono derivative Powerline 字体文件本体也在 OSS 中,但我把 css 文件写在了本地font.css中。

除此以外,对于日文、韩文字体,方正兰亭圆 GBK 并不支持,所以调取了基沃托斯古书馆提供的 Blueake 字体。

综上所述,自定义字体需要准备css文件和字体文件两部分:
css文件可以放在本地docs/stylesheets/目录下,也可以放到服务器上,在mkdocs.yml中调取;
字体文件最好放在服务器上,在css文件中调取。

mkdocs.yml

CSS
1
2
3
4
5
extra_css:
  - stylesheets/font.css  # 自定义字体CSS
  - stylesheets/extra.css # 自定义CSS
  - https://xxx/fonts/FZLanTY/FZLanTY.font.css
  - https://font.kivo.wiki/Blueaka/Blueaka.css

FZLanTY.font.css

CSS
1
2
3
4
5
6
7
8
9
extra_css:
@import url("./FZLanTYK_Xian/font.css");
@import url("./FZLanTYK_Xi/font.css");
@import url("./FZLanTYK_Zhun/font.css");
@import url("./FZLanTYK_Zhong/font.css");
@import url("./FZLanTYK_ZhongCu/font.css");
@import url("./FZLanTYK_Cu/font.css");
@import url("./FZLanTYK_Da/font.css");
@import url("./FZLanTYK_Te/font.css");

font.css (Ubuntu Mono derivative Powerline)

CSS
1
2
3
4
5
6
@font-face {
    font-family: 'Ubuntu Mono derivative Powerline';
    font-style: italic;
    font-weight: 700;
    src: url("https://xxx/Ubuntu%20Mono%20derivative%20Powerline%20Bold%20Italic.ttf");
}

自定义字体的引用

网站不要设计太多的字体,因此直接在extra.css中修改root,指定正文和代码块的字体族即可。

CSS
1
2
3
4
:root {
  --md-text-font: "FZLanTY", "Blueaka";
  --md-code-font: "Ubuntu Mono derivative Powerline", "FZLanTY";
}

Info

排在后面的字体会作为备选字体使用,当前面的字体无法显示时会使用后面的字体。Ubuntu Mono 字体不支持中文,因此把中文字体排在后面可以保证英文显示 Ubuntu Mono,中文显示 FZLanTY

FZLanTY 字体有 8 个字重,可以根据需要在extra.css中指定不同的字重:

CSS
.md-typeset h1{
  font-weight: 800;
}

.md-typeset h2 {
  font-weight: 700;
}

.md-typeset h3 {
  font-weight: 600;
}

.md-typeset li, header{
  font-weight: 400;
}

Info

需要在字体引用的 css 里定义 font-weight 映射的字体。

自定义字体的渲染优化

本文重点其实在这,自定义的字体文件选择什么格式更好,如何渲染带宽更少,都有优化空间。

以方正兰亭圆 GBK 为例,8 个字重的 ttf 文件加起来共 89.8MB,放在网站上显然不合适。并且,ttf 格式的字体在网页上的渲染有锯齿,非常难看。

使用ttf格式的字体渲染

Figure 1. 使用 ttf 格式的字体渲染

那么有什么优化方式吗?

WOFF2 格式字体

WOFF2(Web Open Font Format 2) 是专门为网页设计的字体格式,具有更好的压缩率和加载速度。将 ttf/otf 格式的字体转换为 woff2 格式,可以显著减少文件大小,同时保持较高的渲染质量。

使用woff2格式的字体渲染

Figure 2. 使用 woff2 格式的字体渲染

将方正兰亭圆 GBK 8 个字重转换为 woff2 格式后,文件大小从 89.8MB 减少到约 15MB,加载速度大幅提升,渲染效果也更佳。

即便如此,15MB 的字体文件对于网页来说仍然太大了。我们可以使用子集化技术进一步优化。

字体子集化

字体子集化是指根据实际使用需求,只保留字体文件中需要的字符,从而大幅减少字体文件的大小。对于只使用部分字符集的网站,子集化可以显著降低字体文件的体积。

但如果删除了想要渲染的字符就完蛋了,因此更好的办法是使用 css unicode-range参数,将原始字体文件拆分为数个(甚至几十上百个)woff2 子集文件,每个子集文件只包含特定范围的字符,然后在 css 中使用@font-face分别引用这些子集文件,并通过unicode-range指定每个子集文件对应的字符范围。

CSS
1
2
3
4
5
6
7
8
@font-face {
  font-family: FZLanTY;
  src: url("./FZLanTYK_Cu.74.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+1d2,U+1d4,U+1d6,U+1d8,U+1da,U+1dc,U+1f9,U+251,U+261;
}

每个子集字体文件仅几 KB 到几十 KB,根据网站实际使用的字符范围,加载所需的子集文件即可,大大减少了字体文件的总大小。

字体切片推荐使用 font-slice 这个工具,它是根据 Google Fonts 的切片方式设计的,输入 ttf 或者 otf 字体文件自动导出 woff2 子集和对应的 css 引用。

评论