还在用 来当作空格?别忽视他对样式的影响!

797 阅读4分钟

许久没有更新博客了,今天就抽空来分享下之前遇到个有意思的现象~

奇怪的现象,被换行的单词

在一次新需求完工之后,进行国际化样式优化时,我发现了一个奇怪的现象:即使页面元素有word-wrap:break-word; 样式属性,单词也照样会被直接裁断换行。

image.png

这又是为什么嘞?细细分析页面元素,突然发现或许这与之前的踩过的坑:特殊的不换行空格有关?!

来复现吧!

那我们马上就来试一试!

  <style>
    .normal_style{
      width:70px;
      height:200px;
      margin-right:150px;
      border:1px solid red;
      /* 👇表示 如果一个单词超出行长度,要截取换行,其他默认;👇 */      
      word-wrap:break-word;
    }
  </style>
  
  <div style="display:flex;">
    <div class='normal_style'>This is a long a long sentence</div>
    <div class='normal_style'>This&nbsp;is&nbsp;a&nbsp;long&nbsp;a&nbsp;long&nbsp;sentence</div>
  </div>

image.png

很明显,单词直接被强行换行拆分了!

那会不会是页面解析的时候,把 &nbsp; 连同其他单词一起,当作一长串单词来处理了,所以才不换行的嘞?

你知道空格转义符有几种写法吗?

那我们就再来试试!不使用 &nbsp; 转而使用其他空格转义符呢?

其实除了 &nbsp; ,还有其他很多种空格转义符。

1. 半角空格

&ensp;

它才是典型的“半角空格”,全称是En Space,en是字体排印学的计量单位,为em宽度的一半。根据定义,它等同于字体度的一半(如16px字体中就是8px)。名义上是小写字母n的宽度。此空格传承空格家族一贯的特性:透明的,此空格有个相当稳健的特性,就是其占据的宽度正好是1/2个中文宽度,而且基本上不受字体影响。

2. 全角空格

&emsp;

从这个符号到下面, 我们就很少见到了, 它叫“全角空格”,全称是Em Space,em是字体排印学的计量单位,相当于当前指定的点数。例如,1 em在16px的字体中就是16px。此空格也传承空格家族一贯的特性:透明的,此空格也有个相当稳健的特性,就是其占据的宽度正好是1个中文宽度,而且基本上不受字体影响。

3. 窄空格

&thinsp;

窄空格,全称是Thin Space。我们不妨称之为“瘦弱空格”,就是该空格长得比较瘦弱,身体单薄,占据的宽度比较小。它是em之六分之一宽。

4. 零宽不连字

&zwnj;

它叫零宽不连字,全称是Zero Width Non Joiner,简称“ZWNJ”,是一个不打印字符,放在电子文本的两个字符之间,抑制本来会发生的连字,而是以这两个字符原本的字形来绘制。Unicode中的零宽不连字字符映射为“”(zero width non-joiner,U+200C),HTML字符值引用为: ‌

5. 零宽连字

&zwj;

它叫零宽连字,全称是Zero Width Joiner,简称“ZWJ”,是一个不打印字符,放在某些需要复杂排版语言(如阿拉伯语、印地语)的两个字符之间,使得这两个本不会发生连字的字符产生了连字效果。零宽连字符的Unicode码位是U+200D (HTML: ‍ ‍)。

再次尝试复现-&thinsp;

  <style>
    .normal_style{
      width:70px;
      height:200px;
      margin-right:150px;
      border:1px solid red;
      /* 👇表示 如果一个单词超出行长度,要截取换行,其他默认;👇 */      
      word-wrap:break-word;
    }
  </style>
  
<div style="display:flex;">
    <div class='normal_style'>This is a long a long sentence</div>
    <div class='normal_style'>This&nbsp;is&nbsp;a&nbsp;long&nbsp;a&nbsp;long&nbsp;sentence</div>
    <div class='normal_style'>This&thinsp;is&thinsp;a&thinsp;long&thinsp;a&thinsp;long&thinsp;sentence</div>
</div>

image.png

我们可以看到 &thinsp; 进行转义的话,单词截取换行是正常的!所以,真凶就是 &nbsp; 特殊的不换行空格!

如何修订?

因为这个提示框是使用公司自制的 UI 组件实现的,而之所以使用 &nbsp; 进行转义是为了修订XSS注入。(对,这个老东西现在没人维护,还是我去啃源码加上的,使用了公共的转义方法)。最后就简单去修改这个公共方法吧!使用了最贴近 &nbsp; 宽度的空格转义符:&thinsp;