这篇文章发布于 2016年11月12日,星期六,23:05,归类于 CSS相关。 阅读 80813 次, 今日 7 次 16 条评论
by zhangxinxu from http://www.zhangxinxu.com/wordpress/?p=5742
本文可全文转载,但需得到书面许可,同时保留原作者和出处,摘要引流则随意。
一、unicode-range是什么?
一看名称,很多小伙伴可能认为是个什么生僻的东西,实际上,这玩意只是名字怪怪的,功能关键时刻还是很管用的。
unicode-range
是一个CSS属性,一般和@font-face
规则一起使用。
大家应该不赶时间吧,那我们一点一点往下深入,现在很多网站会使用微软雅黑字体,但是,微软雅黑的名称有点长:
.font { font-family: 'microsoft yahei'; }
如果这个字体不是全局的,每次用到都要写一遍都很烦。虽然说,现在Sass, Less之类东西可以让其成为变量,但是CSS的代码量依旧没有减小。其实,我们可以借助@font-face
这种原生的特性来简化我们的变成成本以及减少代码量,如下:
@font-face { font-family: YH; src: local("microsoft yahei"); }
然后,接下来要使用微软雅黑字体的字体,就不要使用那段长长的很有逼格的字符串了,直接科科:
.font { font-family: YH; }
字体就是微软雅黑字体了,好记又好用,这才是@font-face
真正的实力……的一部分。
iMac等苹果机子上好像默认没有微软雅黑字体,我们希望Mac OS X系统上使用苹方字体,window系统上雅黑字体,也是可以的,我们不妨命名把字体名命名为BASE(全大写表示自定义),然后:
@font-face { font-family: BASE; src: local('PingFang SC'), local("Microsoft Yahei"); }
于是乎,我们的字体就更加智能了,要使用直接:
.font { font-family: BASE; }
结果windows系统下:
OS X系统下:
大家若有兴趣,也可以狠狠地点击这里:雅黑和苹方化身更精简名称demo
本来皆大欢喜,但是敏锐的设计师突然发现,这微软雅黑字体的引号,前后长得都是一样的,大段文章内容中无所谓,但是如果出现在大大的slogon中,显然,不是最好的表现,于是提出了这么一个需求,希望引号全部都是宋体,而其他字体依然是苹方或者微软雅黑。
如果这种需求,我们可以有下面几种做法:
- 晓之以理动之以情否决这个需求,但是,你也少了一个在设计师大显身手的机会;
- 引号外面套用个
span
标签之类,然后设置宋体。但是,如果我们的内容是动态的,啊哦,估计就麻烦了,就需要内容输出的时候匹配替换了。 - 使用字蛛这样的中文字体生成工具,生成一个仅具有上引号和下引号的字体,假设
font-family
命名为quote
,则如下CSS:.font { font-family: quote, BASE; }
但是宋体系统都有,这另外生成外加额外的请求都是成本啊。
- 使用本文的
unicode-range
,也就是我们使用unicode-range
指定就引号使用宋体。如下CSS代码:@font-face { font-family: BASE; src: local('PingFang SC'), local("Microsoft Yahei"); } @font-face { font-family: quote; src: local('SimSun'); unicode-range: U+201c, U+201d; } .font { font-family: quote, BASE; }
此时,原本的一个方向的引号就变得更加传统和直白了(见下图):
若想新眼所见,您可以狠狠地点击这里:unicode-range控制特定字符使用特定字体demo
这里,Firefox浏览器下有个大坑,我爬出来花了好一会儿,就是Firefox浏览器对字体的拼音名称大小写敏感,也就是
local('simsun')
Firefox会当初浏览器默认字体来处理,有些坑,大家需要注意下。
上面4种做法,明眼人都能看出来,unicode-range
是成本最低同时效果最好的实现方式。不知诸位是不是对unicode-range
开始有了兴趣呢?
二、unicode-range的值和语法
unicode-range
的值正如名称所示,是unicode值,就是U+
以及后面可以表示各种字符和文字的几个数字或字母,初始值为:U+0-10FFFF
,也就是所有字符集。
语法如下,参考自MDN:
/*支持的值 */ unicode-range: U+26; /* 单个字符编码 */ unicode-range: U+0-7F; unicode-range: U+0025-00FF; /* 字符编码区间 */ unicode-range: U+4??; /* 通配符区间 */ unicode-range: U+0025-00FF, U+4??; /* 多个值 */
其中,U+4??
有些小伙伴可能不知道什么意思,?
可以理解为占位符,表示0-F
的值,因此,U+4??
表示从U+400
到U+4FF
。
我们扫一扫unicode-range
的语法应该就知道其属性值的组成了,就是U+
跟上对应字符的charCode值。
于是,前端领域字符表示方式又多了一员:
1. HTML中字符输出使用&#x
配上charCode值;
2. 在JavaScript文件中为防止乱码转义,则是\u
配上charCode值;
3. 而在CSS文件中,如CSS伪元素的content
属性,直接使用\
配上charCode值。
4. unicode-range
是U+
配上charCode值。
那有哪些常用的unicode
值范围呢?以及如何获得任意字符的unicode值呢?
三、unicode-range的常用unicode值及获取
对于我们中文用户,最常用的有下面这些:
汉字:[0x4e00,0x9fa5]
(或十进制[19968,40869]
)
数字:[0x30,0x39]
(或十进制[48, 57]
)
小写字母:[0x61,0x7a]
(或十进制[97, 122]
)
大写字母:[0x41,0x5a]
(或十进制[65, 90]
)
关于中文汉字更详尽的编码,我特意整理了一个页面,以及可以预览对应字符范围的所有字符内容。您可以狠狠地点击这里:中文汉字unicode编码范围整理demo
截图效果如下:
左侧的汉字都是可以点击的,然后,我又顺便花时间做了个可以预览unicode-range
范围字符内容的页面,例如unicode-range对应字符显示工具兼显示基本汉字demo
地址后面的range=
写上对应的unicode-range
范围内容,就可以知道对应的都是那些字符了,例如,上面语法那里出现过的U+0025-00FF
,我们看看都是对应哪些内容,我们把url
后面改成如下图:
结果原来指的是这些字符:
某个具体的字符unicode值如何获取?
这就需要我之前在“使用 等空格实现最小成本中文对齐”一文中提到的小工具了,您可以狠狠地点击这里:任意字符转换成HTML识别格式工具页面
例如:
上面的a9
就是我们需要的charCode
值,&#x
是在HTML中显示字符实体用的,这里不用管,然后套永在unicode-range
属性值中就是U+9aU+a9
,一开始的宋体引号例子,我就是使用这个工具获取到U+201c
和U+201d
的。
四、unicode-range适合使用的场景
我看到有部分前端小伙伴使用unicode-range
的场景是这样的,一段内容,英文数字等使用某个字体,中文使用另外一个字体,于是,使用unicode-range
弄了一段自定义编码,看上去很酷,毕竟使用了很多人都不知道的unicode-range
,实际上,这并不是unicode-range
真正适合的应用场景(虽然确实也实现了效果),为什么呢?
比方说你希望数字英文是Helvetica字体,中文是苹方或微软雅黑,直接把英文字体放在前面就可以了!
.font { font-family: Helvetica, 'Pingfang SC', 'microsoft yahei'; }
因为,据我所知,这些英文字体是没有中文字符集映射的,也就是,英文字体实际上对中文是没有任何作用的。考虑到font-family
的字体解析是从前往后依次的,所以,自然而然上面的代码数字英文是Helvetica字体,中文是苹方或微软雅黑,完全不需要使用unicode-range
做吃力不讨好的事情。
那unicode-range
适合使用的场景究竟是什么呢?
在我看来,是对中文内容中的某部分中文字符做特殊字体处理,或者是英文字体中部分字符做特殊字体处理,这个才是适合的。比方说,上面使用宋体引号的案例,因为都是中文字体,因此,才有使用unicode-range
的价值。
补充于2019-01-24
来自某大厂真实项目应用案例。
hello,请教一个问题。我们希望控制文本块的高度,但是对于中文标点字符如“《,。》”之类的,在不同手机上渲染的宽度不太一致,导致文本块高度在一些手机上矮一点。
就可以使用unicode-range
来解决。可以先生成一个只包含“《,。》”这些字符的标准宽度字体,然后使用unicode-range
指向该字体。
最终反馈如下:
unicode-range 方法确实好用,强大
五、unicode-range的兼容性
我擦,caniuse打不开。
兼容性相关JSON数据参见这里。
MDN上显示为:
基本上,IE9+浏览器开始支持,Firefox 44开始支持不错,至于Chrome和移动端,大家自然可以愉快地玩耍。总而言之,兼容性还是很不错的,至少在实际项目中使用我觉得很OK啦。IE8什么的字体效果差点就差点,毕竟不是影响功能的CSS属性。
六、结语
在处理unicode-range
的时候,突然感叹,要是@font-face
规则中可以定义文字的默认颜色就好了,这样,我们要在前端实现搜索高亮效果,根本就不需要对HTML做任何事情,直接把对于的搜索内容转换成unicode编码,使用unicode-range
匹配,自动变得,那就厉害了,可惜不支持。毕竟仅仅是字体匹配似乎不是很明显。
好了,风平浪静的一个星期六,没什么要吐槽的,就这些,感谢阅读,欢迎交流!
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:http://www.zhangxinxu.com/wordpress/?p=5742
(本篇完)
- 真正了解CSS3背景下的@font face规则 (0.488)
- 小tip: 使用CSS(Unicode字符)让inline水平元素换行 (0.410)
- CSS content换行实现字符点点点loading效果 (0.410)
- JS与条形码的生成 (0.410)
- 关于CSS emoji字体和OpenType-SVG我所知道的一些事 (0.351)
- ascent-override descent-override line-gap-override一锅端 (0.351)
- 使用CSS size-adjust和unicode-range改变任意文字尺寸 (0.351)
- 请使用千位分隔符(逗号)表示web网页中的大数字 (0.273)
- 页面可用性之浏览器默认字体与CSS中文字体 (0.239)
- 翻译 - CSS高峰会议内容精选 (0.239)
- 详解日后定会大规模使用的CSS @layer 规则 (RANDOM - 0.078)
太有用了,刚接触css也看得懂,没想到能正好找到我想搞的东西,非常感谢。
不错不错
讲的确实很详细。
但第六点,即使 font-face 能联动控制 unicode-range 的颜色背景,也不能正确的实现前端搜索高亮效果。因为它是查找每个字符,不是匹配短语!
当字符有重复或不是在内容中连读的话,会分散为高亮的单个字符,这是不对的哦。
赞一下!很好用
非常好的教程,我碰到的一個實際問題是我用了CSS強制全局更改字體以後(因為有些網頁必須全局更改才能使字體生效)部分特殊的圖標字符直接變成了方塊無法顯示,不知道用range限定範圍能不能解決這個問題.
路过学习留个痕迹,谢谢!
然而把h1换成div之后 并不是正宗的微软雅黑
前天 看你千分位实现的时候,顺便看了这个。今天就用上了!
感谢,学习了,赞。
好文,学习。
好奇怪鑫哥!我本地使用unicode-range 属性没有效果!我首先查看浏览器的版本在查了兼容!然后再检查了路径然后再检查 unicode-range: U+201c, U+201d;奇怪!为什么会没效果呢
wooo,感谢
第一次了解unicode-range:u+****-u+****;学习了。
涨姿势了(兼容性很好这是一大福音啊
很好的一片文章,总结的挺详细,谢谢博主。
“然后套永在unicode-range属性值中就是U+9a”
此处应该是U+a9吧,还特地用demo页验证了下,以为是什么特别的倒叙写法。。。