前言
这篇看完之后,你可以联想一下这个的应用场景。你曾经是否利用空格来对齐呢?这天这篇来自腾讯UI工程师
Kayo的研究。正文从这开始~
一.概要
在编写HTML模板时,有时候会利用空格来充当文字排版的手段,最为常见的情况是在一段文字之间插入空格,来分隔相对独立的词汇。但面对这种情况,一般是不会直接使用普通空格(半角空格,即英文输入法下键盘直接输入的空格),因为当我们期望连续输入几个这样的空格来制造一段空白时,实际最终网页上显示出的空白大小只有一个空格的大小,因此通常会用nbsp;来代替半角空格,连续输入多个nbsp;会产生相应数量的空白。实际上除了nbsp;外,Unicode还定义了大量特性各异的,包含HTML实体形式的空格字符,本文要研究的正是这些平时相对较少被注意到的空格以及它们的特性。
二.Unicode中有HTML实体形式的空格
以下是Unicode中有HTML实体形式的空格及其产生的空白的效果:
这些空格按特性基本可以分为三类:
1.不换行空格
不换行空格只有nbsp;一种,最主要特性是不会被浏览器判断为可以在中间打断,这也是nbsp;被创造出来的主要用途。这里引用一段简短的介绍:
nbsp;istheentityusedtorepresentanon-breakingspace.Itisessentiallyastandardspace,theprimarydifferencebeingthatabrowsershouldnotbreak(orwrap)alineoftextatthepointthatthisnbsp;occupies.
例如,"Thisisatestfornon-breakingspace"这个句子,如果单词之间的空格都使用半角空格,并把它置于一个宽度刚好不足的容器中时,"space"这个单词会因为宽度不足而单独换行了。
如果想把"breaking"与"space"同时换行,这时只需要把"breaking"与"space"之间的半角空格替换为nbsp;即可:
可以看出,"-"这类普通字符仍然会被浏览器认为是单词的分隔点,而"breaking"与"space"之间由于有nbsp;的连接,由于nbsp;不会被打断,因而浏览器会认为它们是相连的一个完整单词,在位置允许的情况下把它们同时换到下一行。
需要注意的是,如果一大段英文文字中的空格都使用nbsp;,那么浏览器就无法正确识别出哪个字符才是单词的开始和结束,因而无论如何使用word-wrap和word-break等控制单词断开或换行的CSS属性,最终都很难避免在单词中间断开单词,这也往往不是我们想要的结果。因此如果段落中不同单词之间有大量的连续空格,那么这些连续空格的第一个空格最好使用普通的半角空格,以保证单词之间仍有正常的分隔。
2.跟随字体大小产生相应空白的空格
这类空格包含ensp;emsp;thinsp;三个空格字符,这三个空格都会根据不同的字体大小产生相应的空白大小,分别是1/2em,1em,1/6em(有时被设计成1/5em)宽。其空白大小具体表现如下图:
由于中文是等宽字体,因此emsp;和ensp;所产生的空白大小与中文字大小具有明确的比例关系(一个ensp;等于半个中文字的宽度,而一个emsp;则是一个中文字的宽度),因此这类空格很适合用于控制排版,例如:
3.零宽连字控制空格
即zwnj;和zwj;,这两个空格字符并不会产生空白,仅能控制字符之间是否连字,这两个字符也是“不打印字符”(或称作“控制字符”),即不会影响打印效果的字符,仅作字符特性控制。而所谓的连字,是西方字体中常见的现象,表示两个单独的字母在相连时可以连接为新的字母的现象。例如在德语中,"f"与"l"之间连写会变成一个新字符,整个单词对应的语义也会发生改变或者产生不符合语法的情况。例如:
Auf?lage(编辑)是一个德语复合词,由"auf"(关于)和"lage"(位置)两个组成成分构成,在德语语法中,复合词组成成分的边界不能产生连字,因此"f"和"l"之间不应该连字,如果在HTML上直接写入这个单词,直接交由浏览器控制,则会产生如下的效果:
"f"和"l"之间相连了,不符合德语的语法规范,因此需要在两个字母之间插入一个zwnj;强制不连字,效果如下:
值得注意的是,并不是所有的浏览器都对zwnj;和zwj;敏感,目前Chrome(44.0..)中这两个字符并不能产生连字或不连字的控制,而Safari(8.0.6)中则可以有效控制连字。
最后需要强调的是,虽然Unicode中有着各种不同特性的空格可以用于排版,但理论上还是不应该用空格来进行排版,排版应该是CSS负责控制的,用于排版的空格并不属于内容但却与内容混排在一起,实际上相当不利于维护。只有当不便于使用CSS(比如在EML中)等特殊情况时才考虑用空格参与排版。
关于本文
作者:
Kayo原文链接: