1

上一篇博客中介绍white-space属性时聊到了换行,这一篇介绍换行的细节。

浏览器的默认行为

浏览器的换行行为,对于中文和英文存在一些差别。

中文换行

正如上一篇博客中所说的,中文换行比较简单,这一行放不下就换行。除了中文之外,韩文和日文的处理也是一样的。这三种文字合在一起就是MDN介绍word-break属性时所说的CJK(Chinese, Japanese, Korean的缩写)。

英文换行

来到英文,情况就要复杂一些。在英文中有单词的概念,所以在换行时就得考虑单词的完整性。

  1. 浏览器按照空格来识别单词,默认情况下,浏览器不会在单词内换行

    <p> thisisalonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglongword</p>

    我们在p标签内部放了一些英文字母,这些字母之间并没有用空格来分隔开来,这就像文言文没有用标点符号断句一样。所以,就如同你看不懂没有断句的文言文,浏览器也看不懂没有用空格分隔的英文。于是浏览器在处理时,就会把这一长串英文只是当成一个很长很长的单词,只有一个单词也就不会换行,因为默认的换行只会在单词之间。

    识别单词

  2. 当一行放不下时,浏览器会尝试把最后一个单词放到下一行,如果下面这一整个空行还是放不下这个单词,那么就会任由这个单词超出容器,反正默认情况下浏览器是不会把单词拆开的。

    <p> this is a longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglongword</p>

    最后显示时,就会把后面这个长单词放到下一行,然后任由其超出容器:

    以单词为单位换行

word-break属性

从上面的两点看到,浏览器已经在很努力的换行,从而尽量让文字不要超出容器了。但即使是这样,对于较小的容器中存放的长单词,当整个一行还放不下一个单词是,浏览器也是无能为力,毕竟浏览器要保证单词的完整性,不敢随随便便把一个单词给拆了。但是,word-break属性就赋予了浏览器拆单词的权力。

  1. word-break:normal:这是默认值,也就是浏览器的默认行为
  2. word-break:break-all:能把all都break掉,所有的东西都能拆,所以,单词随便拆

    <p style="word-break:break-all">this is a longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglongword</p>

    这样浏览器在排版时,就完全可以把字母当成拆分单位,一个字母一个字母的往上放,放不下时就把字母放到下一行。可以理解成,此时就没有单词的概念了,只有字母。

    ![word-break:break-all]][3]

  3. word-break:keep-all:上面在介绍浏览器的默认行为时,CJK字符和英文是分开,之所以这样,是因为word-break属性对于中英文的行为也是分开的。上面介绍的break-all值,主要也是针对英文的,汉字还是按照浏览器的默认行为,装不下就换行。对于中文来说,没有拆分不拆分,只有换行不换行。keep-all就是让中文不要换行,此时英文还是按照浏览器的默认行为来。

    <p style="word-break:keep-all">this is a longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglongword 这是中文这是中文是中文这是中文这是中文这是中文是中文这是中文这是中文这是中文是中文这是中文这是中文这是中文是中文这是中文这是中文这是中文是中文这是中文这是中文这是中文是中文这是中文这是中文这是中文是中文这是中文</p>

    注意这里我在中英文之间加了个空格,否则浏览器会把后面的中文页当成是英文单词的一部分。最后显示时,英文还是按照默认行为,中文变成了不换行。

    word-break:keep-all

  4. word-break:break-word:在MDN上,只会介绍前面三个属性,因为只有前三个才是标准的,而break-word是非标准的。如果一定要使用这个值,就需要注意下浏览器的兼容性,其最后显示的效果,跟下面介绍的word-wrap:break-word基本一致,这里不再多说,看下面吧。

word-wrap属性

word-break:break-all在拆英文单词时,细看一下,当longlonglon...longword这个单词在第一行末尾放不下时,其实是分了两步:

  1. 以字母为单位处理,尽量将这个长单词的字母往第一行放,能放多少放多少
  2. 后面连单个字母都放不下时,再换行,放其他字母。

word-wrap:break-word则不同,他会首先直接换行,放单词,第二行放不下,再拆单词

<p style="word-break:break-word">this is a longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglongword</p>

word-wrap:break-word

与上面的word-break:break-all的图对比一下就明白了,拆单词也是拆单词,只不过我先换到下一行再拆。

另一个属性值是word-wrap:normal,这就是默认值,对应浏览器的默认行为。

word-breakword-wrap很容易弄混,所以在CSS3中,word-wrap已经改成了overflow-wrap,不过考虑兼容性,还是用word-wrap的比较多。

总结一下

word-break:break-allword-wrap:break-word这两个属性,都是考虑拆英文长单词的,但是拆分的方法有点不一样。另外word-break:keep-all还可以控制中文。其实想想,还是中文的事少,没有拆分的顾虑,只用考虑换行不换行就可以了。


程序员不止程序猿
177 声望7 粉丝