任何一个网页设计师或前端设计师都对@font-face非常熟悉,它有一个看起来很无聊的属性:unicode-range。不过正是这个不起眼的属性,我们却可以轻松地利用它通过CSS创造出字体混搭的效果。

本文的全部代码来自http://24ways.org/2011/unicode-range,如果您对其中的任何技术细节存在疑问,请以原文为准。

Unicode-range

unicode-range属性是@font-face中的一项属性,其作用是告知浏览器,通过@font-face引入的字体覆盖了unicode字符体系的哪些部分,以便浏览器仅在该范围内使用该字体。

@font-face {
    font-family: BBCBengali;
    src: url(fonts/BBCBengali.ttf) format("opentype");
    unicode-range: U+00-FF;
}

上面的代码调用了一个名为BBCBengali的字体,同时告知浏览器,其覆盖范围是从U+00U+FF,亦即unicode字符表当中的前256个字符。

因此,通过多个带有不同区域覆盖的@font-face规则,开发者可以将多个字体拼接在一起使用。

更有趣的是,如果我们只在范围中选择某个字符,那么我们就可以巧妙地制造出字体的混搭效果。

不错的方案一

如果我们希望用一种字体当中的&符号,但其他的字符使用另外的字体,你会怎么做?

如果没有CSS3,我们或许会通过这样的方式来解决这个问题:

&

单独地将符号放在一个span标签内,

span.amp {
    font-family: Baskerville, Palatino, "Book Antiqua", serif;
}

然后为它创建一条CSS规则。

这个方案很不错,它已经准确地实现了我们想要的效果。但是还不够漂亮。因为每当我们需要使用这个特别的符号时,我们就不得不使用一个span来包裹它,而这并不总是可行的,尤其是我们不想给用户提供HTML语法支持的时候。

漂亮的方案二

现在我们来看看如何用unicode-range来搞定它。符号&的unicode编号是U+26,所以我们只需要这样写即可:

@font-face {
    font-family: 'Ampersand';
    src: local('Baskerville'), local('Palatino'), local('Book Antiqua');
    unicode-range: U+26;
}

h1 {
    font-family: Ampersand, Arial, sans-serif;
}

非常简洁省事,我们漂亮地完成了这个问题。我们首先创建了一个新的font-family,紧接着将特定的字体安排在unicode-range恰好是U+26的位置。最后,我们只要将这个font-family放在其它font-family的前面即可。

浏览器不给力了

貌似也太简单了。简单到如果没有一点问题就感觉不可思议的地步。这回我们的麻烦是,浏览器支持情况。

Webkit引擎的浏览器目前都已支持了unicode-range属性,而最新版IE也已经支持了该属性。问题是,火狐不支持。

我们期望浏览器良好地回避它,就像IE8对待圆角属性border-radius一样——如果不支持,直接忽略即可——但事实上,这个属性的不支持可就与我们想象的相差甚远了。

如果unicode-range属性得不到支持,那么类似于上文的代码,其字体覆盖范围不会变成空,相反,它的覆盖范围会默认地变为全范围。也就是说,我们新创建的这个font-family,会覆盖到所有的字符,而这可不是我们想要的。

目前,火狐方面已经开始着手处理这一BUG了(Bugzilla),但真正在发行版中干掉它还有一段时间。

回避策略

我们不会袖手旁观的。如果浏览器不能实现回避,那么我们自己来搞定它。

简单来说,火狐会将我们设置的覆盖范围完全无视,进而铺设到全部范围之上,那么我们的回避策略就是:使用第二条规则覆盖掉第一条。

@font-face {
    font-family: 'Ampersand';
    src: local('Baskerville'), local('Palatino'), local('Book Antiqua');
    unicode-range: U+26;
}
@font-face {
    font-family: 'Ampersand';
    src: local('Arial');
    unicode-range: U+270C;/* 注意,没有这一条火狐依然不正常 */
}

上面的代码在我们原先的第一条规则之后又增加了一条规则。

  • 当火狐遇到第二条规则时,它会用第二条规则覆盖掉第一条,那么只有Arial会出现了。这正是我们需要的回避。
  • 如果浏览器支持unicode-range,那么第二条规则将覆盖掉一个我们并不会用到的字符,因此并不影响第一条规则。

唔,U+270C万一真的要用到呢?你真的会用到吗?它实际上是一个“胜利手势”:

About liuyanghejerry

富有激情的前端工程师,专注GUI开发。

Comments are closed.

Post Navigation