Quantcast
Channel: w3cplus
Viewing all articles
Browse latest Browse all 1557

CSS秘密花园: 花式的&符号

$
0
0

CSS Secrets》是@Lea Verou最新著作,这本书讲解了有关于CSS中一些小秘密。是一本CSSer值得一读的一本书,经过一段时间的阅读,我、@南北@彦子一起将在W3cplus发布一系列相关的读后感,与大家一起分享。

CSS Secrets

花式的&符号

几个漂亮的&符号,在大多数电脑上都有;从左到右分别是:Baskerville, Goudy Old Style, Garamond, Palatino(全部都是斜体)。

你会在印刷文献中发现很多有不显眼的&符号。设计良好的&符号是非常优雅的,其它的符号都很少能像它这样。整个网站都在致力于寻找有最好看&符号的字体。但是,拥有最好看&符号的字体,却往往不是那个你希望应用于其它文本的字体。毕竟,真正漂亮和优雅的标题效果,总是一个好的无衬线字体和一个漂亮而且复杂的衬线符号的结合。

Web设计师前阵子意识到了这一点,但用来实现它的技术是相当粗浅而且繁琐的。它们通常是用一个<span>元素来包裹每一个&符号,通过脚本或手动添加,如下:

HTML <span class="amp">&amp;</span> CSS

然后,我们为.amp类应用如下的字体样式:

.amp {
    font-family: Baskerville, "Goudy Old Style",Garamond, Palatino, serif;
    font-style: italic;
}

这是可行的,你可以在下图中对比上下两个。

花式的&符号

但是,实现它的技术是相当混乱的,有时候甚至完全不可能的,在我们不能轻易修改HTML标签的情况下(如,当使用CMS的时候)。难道我们就不能只是告诉CSS,我们只想给某些字符添加样式吗?

解决方案

事实证明,我们是可以这样做的,使用不同的字体给某些字符添加样式(甚至是给某类字符),但是完成的方法可能不如你想的那样简单。

我们通常会在font-family声明中指定多种字体(字体栈),这样当我们的首要选择不可用的时候,浏览器可以降级使用其它字体,也符合我们的设计。然而,很多作者忘了这也是基于每个字符的。如果字体是可用的,但只包含几个字符,该字体将会应用于它有的这些字符;然后对于其它字符,浏览器将会降级使用其他字体。这适用于本地字体和通过@font-face规则嵌入的字体。

如果我们有一种字体是只有一个符号的(猜猜是哪个!!),它就可以用于那个字符,所有其它的字符将会按照我们的字体栈中的第二种、第三种等等字体的样式显示。所以,我们现在就有了一个简单的方法来给&符号添加样式了:创建一个只包含我们想要的那个&符号的web字体,通过@font-face调用它,然后把它放在你字体栈中的第一个位置:

@font-face {
    font-family: Ampersand;
    src: url("fonts/ampersand.woff");
}
h1 {
    font-family: Ampersand, Helvetica, sans-serif;
}

虽然这种方法灵活性非常好,但并不理想,如果我们是想用系统内置字体中的一种给&符号添加样式呢?创建一个字体文件不仅非常麻烦,还增加了额外的HTTP请求,更别提潜在的法律问题,如果字体要禁用子集呢。这里有没有办法可以使用本地字体呢?

你可能知道@font-face规则中的src描述符还接受一个local()函数,用于指定本地字体名称。因此,除了单独的web字体,你还可以改为指定本地的字体栈:

@font-face {
    font-family: Ampersand;
    src: local('Baskerville'),
         local('Goudy Old Style'),
         local('Garamond'),
         local('Palatino');
}

但是,如果你现在尝试使用Ampersand字体,你会注意到我们的衬线字体将被应用于整个文本,因为这些字体中包含所有的字符。

花式的&符号

不过这点小挫折这并不意味着我们的方向错了;它只是说明我们缺少一个描述符来声明,我们只关心来自这些本地字体的&字符。这个描述符是存在的,它的名字是unicode-range

unicode-range描述符只在@font-face规则中可用(也被称为术语描述符,它不是CSS属性),限制子集中对字符的使用。它在本地和远程字体中都是有效的。有一些浏览器甚至智能到,只要这些符号在页面中没有使用到,它就不会下载远程字体!

可惜的是,unicode-range的语法比较隐蔽,正如它的应用中是非常好用的。它使用的是unicode代码点,不是转义字符。因此,在使用它之前,你需要找到你想要的字符对应的十六进制编码值。有许多在线资源可以用,或者你可以直接在控制台中输入下面的js片段即可:

"&".charCodeAt(0).toString(16); // returns 26

注意:String#charCodeAt()返回不正确的结果,超过了BMP(基本多文种平面)的范围。但是99.9%的字符你都需要在里边查找。如果你得到的结果是在D800-DFFFF的范围内,那么你就有一个“非常大”的字符,这时候你最好使用一个适当的在线工具来找出它的unicode代码点。ES6方法String#codePointAt()可以解决这个问题。

现在你拿到对应的十六进制编码值,你可以在它们前面加上U+,这样你就已经指定了一个字符了!这是我们的&用例的声明:

unicode-range: U+26;

如果你想要指定一个范围的字符,你还是只需要一个U+即可,像:U+400-4FF。事实上,对于这种范围,你可以使用通配符把它指定为U+4??。多个字符或多个范围也是可以的,用逗号分隔,如U+26, U+4, U+2665-2670。在这里,我们只需要一个字符就OK。所以我们的代码如下:

@font-face {
    font-family: Ampersand;
    src: local('Baskerville'),
         local('Goudy Old Style'),
         local('Palatino'),
         local('Book Antiqua');
         unicode-range: U+26;
}
h1 {
    font-family: Ampersand, Helvetica, sans-serif;
}

如果你尝试了,你可以看到结果。

花式的&符号

事实上,就是给我们的&符号应用了一个不同的字体!但是,这个效果并不是我们想要的那个。图5.19中的&符号是从Baskerville字体的斜体变形得来的,一般情况下,衬线字体都是斜体的&字符比较好看。我们不能直接给&添加样式,那怎么样才能让它显示成斜体呢?

我们的第一个想法可能是在@font-face规则中使用font-style描述符。但是,这不会有我们想要的效果。它只是告诉浏览器说我们要让这些字体显示成斜体。因此,它会使得我们的Ampersand字体被直接忽略,除非整个标题都是斜体的(在这种情况下,我们确实可以得到非常漂亮的斜体&符号)。

可惜,唯一的解决方案非常麻烦:不是使用font family,我们需要使用我们想要的那个字体的style/weightPostScript名称。所以,为了得到我们使用的字体的斜体版本,我们最后的代码如下:

@font-face {
    font-family: Ampersand;
    src: local('Baskerville-Italic'),
         local('GoudyOldStyleT-Italic'),
         local('Palatino-Italic'),
         local('BookAntiqua-Italic');
         unicode-range: U+26;
}
h1 {
    font-family: Ampersand, Helvetica, sans-serif;
}

备注:在Mac OS X上查找字体的PostScript,在FontBook应用中选中它并按⌘I

最后我们得到了我们想要的&符号,如图:

花式的&符号

可惜,如果我们想要再为它们添加自定义样式(如,增大字体尺寸,减少透明度,或其它的自定义操作),我们需要去HTML元素中修改。但是,如果我们只是想要一个不同的字体和某个字体不同style/weight,这个技巧非常好用。基本思路是相同的,你可以使用不同的字体、符号、标点给数字添加样式,它有无限的可能性!

如需转载,烦请注明出处:http://www.w3cplus.com/css3/css-secrets/fancy-ampersands.html


Viewing all articles
Browse latest Browse all 1557

Trending Articles