Rumah > Artikel > hujung hadapan web > CSS秘密花园: 花式的&符号_html/css_WEB-ITnose
《 CSS Secrets 》是 @Lea Verou 最新著作,这本书讲解了有关于CSS中一些小秘密。是一本CSSer值得一读的一本书,经过一段时间的阅读,我、@南北和@彦子一起将在W3cplus发布一系列相关的读后感,与大家一起分享。
几个漂亮的 & 符号,在大多数电脑上都有;从左到右分别是:Baskerville, Goudy Old Style, Garamond, Palatino(全部都是斜体)。
你会在印刷文献中发现很多有不显眼的 & 符号。设计良好的 & 符号是非常优雅的,其它的符号都很少能像它这样。整个网站都在致力于寻找有最好看 & 符号的字体。但是,拥有最好看 & 符号的字体,却往往不是那个你希望应用于其它文本的字体。毕竟,真正漂亮和优雅的标题效果,总是一个好的无衬线字体和一个漂亮而且复杂的衬线符号的结合。
Web设计师前阵子意识到了这一点,但用来实现它的技术是相当粗浅而且繁琐的。它们通常是用一个 元素来包裹每一个 & 符号,通过脚本或手动添加,如下:
HTML <span class="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/weight 的 PostScript 名称。所以,为了得到我们使用的字体的斜体版本,我们最后的代码如下:
@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,这个技巧非常好用。基本思路是相同的,你可以使用不同的字体、符号、标点给数字添加样式,它有无限的可能性!