@font-face 概述
@font-face是一个CSS3新增的一个@
规则,通过自备字体包的方式,允许开发者指定网页的字体,消除网页对用户电脑字体的依赖。
使用方式如下:
@font-face {
font-family: 'myFont';
src: url('path/to/font');
font-weight: 400;
font-style: normal;
}
一般会指定多个url,引入该字体的多种格式文件(eot、woff、tff、svg、otf),增加浏览器兼容性。但是以目前最新的浏览器支持度来看,几乎所有浏览器都支持TTF/OTF这两种字体格式了。所以如果不需要兼容一些旧浏览器,可以只引入TTF或OTF的字体格式文件即可。
font-weight
和 font-style
不写也可以,默认值就是400
和normal
。但是通过指定这两个值,可以对同一字体使用不同的字体文件。
例如:
@font-face {
font-family: 'myFont';
src: url('path/to/font-normal');
font-weight: 400;
}
@font-face {
font-family: 'myFont';
src: url('path/to/font-bold');
font-weight: 700;
}
这样定义后,在css中指定使用myFont
字体,并指定font-weight:400
时,就会使用第一个@font-face
规则; 如果指定font-weight:700
时就会使用第二个@font-face
规则
@font-face 带来的困扰
因为@font-face引入了字体包,页面首次加载的时候浏览器需要下载这些字体包,而在字体文件加载完成之前,浏览器会使用缺省字体显示内容。这种情况叫 FOUT(Flash Of Unstyled Text)。但是这里会有一个问题,除了IE,其他浏览器都会等待3秒后才显示默认字体,这就会造成3秒的字体缺失。这种情况叫FIOT(Flash Of Invisible Text)。
(图片来自网络)
解决困扰
上述问题我们可以通过检测字体加载完成后给页面运用自定义字体。目前CSS3的Font Loading API 可以用来解决这个困扰,但是还是处于草案阶段,不适合生产环境。(后续补充该用法)
这时就轮到字体加载库出场了,github上有不少字体加载的库,比较好的有Font Face Observer和Web Font Loader。我个人比较喜欢Font Face Observer
的用法
这样就可以借助这个库,在字体加载完成后,给根元素加个Class,使用我们自定义的字体,这样就可以避免FOIT的情况。
首先定义@font-face和使用字体的类
@font-face {
font-family: 'SourceHanSans';
src: url('../font/SourceHanSans/SourceHanSansCN-Normal.otf');
font-weight: 400;
}
@font-face {
font-family: 'SourceHanSans';
src: url('../font/SourceHanSans/SourceHanSansCN-Bold.otf');
font-weight: 700;
}
.f-shs body {
font-family: "SourceHanSans", "PingFang SC", "Helvetica Neue", Helvetica, Arial;
}
body {
font-family: "PingFang SC", "Helvetica Neue", Helvetica, Arial;
}
页面默认是使用body元素选择定义的字体,没使用SourceHanSans
字体,所以页面不会出现FOIT的情况。然后使用Font Face Observer
在字体加载完成后,给html根元素加上f-shs
的类名
import FontFaceObserver from 'fontfaceobserver'
let shsNormal = new FontFaceObserver('SourceHanSans')
let shsBold = new FontFaceObserver('SourceHanSans', {
weight: 700,
})
Promise.all([
shsNormal.load(null, 60000),
shsBold.load(null, 60000)
]).then(() => {
document.documentElement.className += 'f-shs'
})
这样就实现了FOUT的效果,而不会出现3秒的字体缺失问题。