最近在写CSS的时候遇到了一个问题,有一个高度属性值不合法:
从肉眼看没什么不妥,根据以往经验,这应该是有特殊的空格导致,把它endcode一下,果不其然:
查了一下,这是一个发宽空格,Unicode编码为U+200A。故借此把常见的普通和特殊空格整理一翻。
(1)普通空格(U+0020)
这是最常用的空格,拉丁文的空格,ASCII编码0x20。在英文输入法(和中文输入法半角状态)下,由键盘空格键直接输出。这个空格的宽度会受到所使用的字体的影响:
例如在上图所示的这个字体,空格的宽度为69(这个是相对于em来说的,这个字体的em大小为256),我们可以把它改大一点,然后生成一个新的字体,使用这个新的字体,空格被渲染出来的宽度便会变大。
(2)不间断空格(U+00A0, )
在HTML里面这应该算是第二常用的空格了,它的HTML实体为“ ”(No-Break SPace)。当HTML有多个连续的普通空格时,浏览器在渲染时只会渲染一个空格,而使用这个不间断空格,可以禁止浏览器合并空格。常用于富文本编辑器之中,当我们在富文本编辑器连续敲下多个空格时,最后输出的内容便会带有很多不间断空格。如下图所示,实际表现为一个普通空格加一个不间断空格连续交替:
在Mac电脑上通过Alt + Space可以打出一个不间断空格。
(3)零宽空格(U+0200B,​)
相信不少人在这个零宽空格上摔过跤,特别是当从一些网页拷了一些东西到代码里面去的时候,然后再做一些字符串处理出现了一些神奇的事情,如下图所示:
为什么明明只有4个字符,长度却是5呢?我们把它encode一下就会发现,其实字符串里面带了一个零宽字符:
零宽空格的UTF-8编码便为0xE2808A。
零宽空格广泛使用于第三方的富文本编辑器里面,常用于格式隔断,例如当你在一个富文本编辑器里面选中一段文字加粗后,如果啥也不干,接着在这选中的文字后面键入的文字便会自动加粗,为了把格式隔断,可以在加粗后的文字后面手动插入一个零宽空格,这样用户在接着往后输时便不会自动延续格式了。
由于网页上有相当多的内容是通过富文本的编辑器产出的(例如WordPress和这篇博文),所以当我们在一个网站上拷贝内容的时候很容易就拷到一个零宽空格。
HTML的<wbr>标签的作用也相当于一个零宽空格,可用于隔断英文单词进行换行。如MDN举的一个例子:
这个标签和上面使用HTML实体的区别在于,这个标签是无法被拷到纯文本里面的,而HTML实例或者使用JS字符串的方式是可以的,因为它本身就是纯文本的一部分(Unicode),标签则不是。
ESLint有一条禁止不规则的空白 (no-irregular-whitespace)的规则,防止代码里面误拷贝了一些诸如零宽空格类的空格,以免造成一些误导。
(4)全宽空格(U+3000, )
普通的U+0020是半角空格,与此相对还有一个全角空格,也叫全宽空格,即一个em大小,在fontforge里面可以看到当前字体的em大小:
这个字体的em为256,一个全宽的字符就是1em,所有的汉字和标点符号的宽度往往被设计成1em。所以全宽空格就和一个汉字同宽。
一个EM方块(EM Square)如下图红框所示:
一个字体在设计的时候不一定是在EM方块里的,看设计师的想法,有可能会超出,如上面的“@”符号,超出的效果是会导致设置font-size的时候实际渲染的高度会比设置的值会更大,例如设置font-size为100px,如果没有超出,那么当前文字高度便为100px,反之会变大。实际看的是ascent和descent的设置:
所以使用不同的字体设置相同的字号,但实际的大小却不一样,便是这个原因。高度超出的比较常见,宽度超出的较少,特别是中文,一般不会超出宽度,所以一个全宽空格宽度便和一个普通汉字的宽度一样大。
(5)半宽空格(U+2002, )
全宽用em表示,半宽则用en表示,为em的一半。半宽空格可用于一些对齐的目的,如三个汉字和四个汉字的两边对齐:
注意全宽和半宽字符理论上不会受到字体影响,如果字体有这两个符号的话,那么应当遵循规范,将这两个字符的宽度分别置为1em和0.5em,否则直接让这两个字符缺失即可,如:
在fontforge里面打叉就表示符号缺失。
除了半宽,还有三分之一宽(U+2004)、四分之一宽(U+2005)和六分之一宽(U+2006)
(6)发宽空格(U+200A, )
零宽空格的前一个便为发宽空格(hair space),网上关于这个空格的介绍几乎没有,只是说它是一个最窄宽度的空格(像头发一样窄,所以叫发宽)。这个也是开篇提到的空格类型,是从Mac的文件夹里的文件信息窗口里拷的:
为什么Mac要用这个空格呢?可能出于Mac的设计审美,普通空白宽度过大,而用发宽空白可能刚好。
除了以上提到的空格外,还有专门用于数学的空格、在德语里用来隔开连词的空格,等等,更多类型空格可见维基百科《空格》。
niu