前端字体

发布于: 8/18/2022 阅读大约需要5分钟

字体格式

格式由旧到新

  • EOT:format('embedded-opentype')
  • TTF:format('truetype')
  • WOFF:format('woff')
  • WOFF2:format('woff2')
  • WOFF2 同字体下体积最小。
  • 可以使用GZIP压缩EOT、TTF格式,因为它们默认不会被压缩。

可变字体(文字变体)

什么是可变字体?

我们可以参考MDN对于可变字体的定义

Variable fonts guide
可变字体允许将同一字体的多个变体统合进单独的字体文件中。

可变字体到底可变在哪里?

通常我们在前端使用字体的时候会根据具体需求引用目标字体的特定样式或多个样式,比如我们要使用一个字体的标准形式、加粗形式以及斜体形式,那么我们理论上应该引用该字体的三种对应字体文件:font-regularfont-boldfont-italic

补充:
有些同学可能有疑问,我们平时开发这些字体样式只是引用一种标准字体然后通过设置样式 font-weight: bold;font-style: italic;不就可以了吗?为什么还要引入对应文件?
因为使用CSS样式对字体进行加粗与倾斜是通过浏览器自己计算进行渲染的,其精度及具体效果并不如原字体设计来的要好,甚至在某些字体下会产生比较明显的差异。
比如我们只引用一个字体文件,那么调整 font-weight 的值在 100500 之间你很难发现字体有什么变化(boldbolder也是一样),这是因为这些值都只会让字体在 normalbold 之间进行变化。

可变字体就是这些情况的排列组合都放进一个字体中,所以可变字体可以精准的体现我们对字体样式所做的调整,正因如此,可变字体的体积会比常规的标准字体文件要大一些。

如何控制字体样式?可控制的样式有哪些?

我们可以通过 font-variation-settings 来控制字体的可变轴

声明字体

我们可以适用 @font-face来声明字体, 声明字体常用属性如下

  • font-family: 字体名称
  • font-style:字体样式
  • font-weight:字体粗细
  • src:以逗号分隔的资源优先级列表,如果高优先级的未找到则会去尝试加载下一级资源。
    • local:加载本地字体。
    • url:加载外部字体。
      • format:(可选)表明外部资源格式, 如果用户环境不支持该格式则不会下载该资源。
  • unicode-range字体适用范围
@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
        url('/fonts/awesome.woff2') format('woff2'),
        url('/fonts/awesome.woff') format('woff'),
        url('/fonts/awesome.ttf') format('truetype'),
        url('/fonts/awesome.eot') format('embedded-opentype');
}

浏览器加载字体的流程

  1. 浏览器加载页面布局,确定页面所需的字体。
  2. 对应每种需要的字体,浏览器会检查本地是否可以提供该字体。
  3. 如果本地无法提供该字体, 则浏览器会遍历外部资源定义(src)。
    • 如果存在格式提示(format),浏览器会先检查是否支持该格式,如果不支持则会直接跳过该资源进行下一资源检验。
    • 如果不存在格式提示(format),浏览器会直接下载该字体资源(url)。

根据上面流程,我们应该始终将本地资源(local)加载放在src的最高优先级
随后的优先级按照格式由新到旧进行加载(如果字体确实有这么多格式的话)
WOFF2 -> WOFF -> TTF -> EOT

unicode字体范围

unicode-range用来定义字体资源的字体显示范围,可以有以下几种写法

  • 单个字符编码:unicode-range: U+30
  • 字符编码区间:unicode-range: U+400-4ff
  • 通配符:unicode-range: U+4??
  • 上面几个的组合:unicode-range: U+27, U+4??

常见的unicode范围

字符集字数Unicode范围
数字(0~9)1030-39
小写英文字母2661-7a
大写英文字母2641-5a
基本汉字209024E00-9FA5

我们可以使用 '字'.charCodeAt(0)来获取指定字符的 Unicode值
补充知识:

  • HTML中字符输出:&#x + Unicode值
  • 转义:\u + Unicode值
  • CSS伪元素content\ + Unicode值
  • CSS字体unicode-rangeU+ + Unicode值

使用字体

CSS中通过配置 font-family 属性来使用字体。

.title {
  font-family: 'Pingfang SC', 'microsoft yahei';
}

由于font-family是从左到右进行取值的,所以我们可以实现标点一个字体、英文一个字体、中文一个字体这样的需求。

.multi-fonts {
  font-family: '标点字体', '英文字体', '中文字体';
}

当然, 这种用法还可以一直细分下去,就不一一举例说明了。

压缩字体

可以使用字体压缩工具对 EOT 和 TTF 字体进行压缩, 比如字蛛。

字体闪动

字体闪动指的我们引用了其他字体之后,在页面内容加载完成时所出现的字体延迟加载或者字体样式瞬间变化的现象。
出现该现象的原因是因为浏览器需要在页面内容加载完成之后才能去解析页面内容,从而决定需要加载的字体(期间还判断unicode-range是否满足)
我们可以通过设置 font-display属性来决定字体加载行为

  • auto: 默认
  • block:先隐藏文字,待字体加载完成再显示文字
  • swap:先使用备用字体,当目标字体加载完成后再切换到目标字体
  • fallback:相当于有时间限制(3s)的swap
  • optional:同fallback,只不过未在时间限制内加载的目标字体会在后台继续加载,以便下次进入的时候使用目标字体。

相关链接