调整字号

@font-face 最佳实践

要想在网页上用一种好看的字体或者 iconfont,都离不开 @font-face,实际使用起来为了兼容各个浏览器,经常需要写一长串的 @font-face 定义,今天来研究一下 @font-face 定义的最佳写法。

浏览器支持情况

IE 6-8 仅支持 eot 格式,现代浏览器基本都能支持四种格式:otf、ttf、woff 和 svg,部分较老的版本可能只支持到 otf 和 ttf。其中 woff 是 W3C 推荐的字体格式。svg 主要用来兼容老的 iOS,如 iOS 4.1 及更早版本。现在应该几乎没人用这么老的 iOS 了吧,所以基本上 eot、ttf 加 woff 就可以很好地兼容目前的桌面和移动浏览器了。

更具体的支持情况可以上 caniuse.com 查询。

最佳实践

@font-face {
  font-family: "MyFont";
  font-weight: normal;
  font-style: normal;
  src: url("myfont.eot");
  src: url("myfont.eot?#iefix") format("embedded-opentype"),
       url("myfont.woff") format("woff"),
       url("myfont.ttf") format("truetype"),
       url("myfont.svg#myfont") format("svg");
}

声明中有两条 src 定义,第二条覆盖了第一条,所以浏览器都会先来读取第二个 src。跟 font-family 的查找一样,浏览器会逐个读取,找到一个支持的格式使用。eot 格式后面所附带的 ?#iefix 是针对 IE 6-8 的 hack。

IE 6-8 是不支持 format() 这种格式说明的,只会读取类似 src:url() 这样的格式,所以 IE 6-8 会把第一个引号到最后一个引号之间的内容都当做字体的 URL,结果就会返回一个 404。因此可以加上一个 ?,后面的内容就成为一个查询字符串,解决了 404 的问题。iefix 在这里是类似于注释的东西,你可以随便写。另外在一部分 Apache 服务器中,缺少了 # 会返回 403,所以再加上 #

再说说第一条 src 定义,它是为了解决 IE 9 兼容模式下的问题的。IE 9 有四种渲染模式,分别是 IE 5、7、8、9 模式。当以 IE 7 或 IE 8 模式运行时,上面那个 bug 被微软修复了,也就是不会再从第一个引号读到最后一个了。但读到 format() 的时候照样不认识,所以把这条定义看做不合法,此时就会回退到第一条 src 定义。所以第一条 src 里不能有 format()

另外一种写法

还发现一种写法是这样,也不错:

@font-face {
  font-family: "MyFont";
  font-weight: normal;
  font-style: normal;
  src: url("myfont.eot");
  src: local("☺"),
       url("myfont.woff") format("woff"),
       url("myfont.ttf") format("truetype"),
       url("myfont.svg#myfont") format("svg");
}

local() 可以直接使用系统已安装的字体,在 local() 里提供一个字体名,如果系统已安装,那么就省去了下载的时间。但这又会产生一种风险,如果用户确实装了这个名字的字体,但又不是你想用的,那最终渲染的结果就很不可控了。所以在这 local() 还是用来搞定对 IE 的。因为 IE 6-8 不认识 local(),所以就会返回到上一条 src,IE 9 兼容模式也被分分钟搞定。用了一个 符号是为了避免正好跟某个字体名相撞,在现代浏览器中因为找不到叫 的字体,所以会直接跳过。

参考资料

Written with StackEdit.

还没有评论,沙发空缺中……
flight