CSS 中有一对容易让人混淆的规则,word-breakword-wrap。我们常常用它们进行换行的控制,不过我基本是处于用完就忘的状态,这次趁着机会总结一下关于它们的知识。

word-break

在介绍它之前,我们先理解一个名词,soft wrap opportunity。soft wrap opportunity 指的是能够换行的断点位置,例如在大多数的书写系统里,空格和标点符号就是 soft wrap opportunity,排版时会在这些位置进行换行。

CSS 中的 word-break 就是用来定义 soft wrap opportunities。它支持以下几个值:

说明
normal 默认换行规则,只有在 soft wrap opportunity 能够换行
break-all 为了防止溢出,单词可以在任意为止被拆分来满足换行(中文、日文、韩文除外)。
keep-all CJK(中文、日文、韩文)中的「单词」不会被拆分,非 CJK 会使用 normal 的规则。
break-word 与设置了 word-break: normaloverflow-wrap: anywhere 具有同样的表现。

break-allkeep-all 的区别在于 CJK 中的「单词」是否会被拆分,可我寻思着长这么大也没见过中文里有单词这东西呀。事实上,这个单词其实就是标点符号或空格前的部分。具体表现如下:

word-break: normal 可被拆分,所以「号,」被换到了下一行。

word-break: normal

word-break: keep-all 不可被拆分,所以「我后面有符号,」这个单词都没被换行。可以理解为一个很长的英文单词在 normal 的值下也不会被分割换行。

word-break: keep-all

word-wrapoverflow-wrap)

word-wrap 用来解决不可分割文字溢出的情况,被重命名为 overflow-wrap(单看 word-wrap,实在是难以想到它是用来解决溢出)。overflow-wrap 的兼容性并不如 word-wrap,不过差别不大,具体参见 caniuse。它支持以下几个值:

说明
normal 在正常的换行点换行,例如两个单词中的空格。
anywhere 为防止溢出,表示如果行内没有多余的地方容纳该单词,则那些正常的不能被分割的单词会被强制分割换行(如长字或URL)。但是在计算最小内容内在尺寸(min-content intrinsic sizes)时会考虑 anywhere 所产生的 soft wrap opportunities。
break-word anywhere,但是在计算最小内容内在尺寸(min-content intrinsic sizes)时不会考虑 break-word 所产生的 soft wrap opportunities。

normal 还能理解,anywherebreak-word 的那一大串说明到底是在说啥?看不明白就测试一下表现,然而 anywhere 在 chrome 中竟然是一个非法值,于是只能去找备胎 firefox。

anywherebreak-word

啥是最小内容内在尺寸( min-content intrinsic sizes)?从 W3C 又是一串说明,简单来说,min-content intrinsic sizes 就是不会导致文本溢出并且尽量换行的最小宽度。那么计算最小内容内在尺寸和 soft wrap opportunities 又有什么关系呢。计算最小内容内在尺寸要求尽量换行,而 soft wrap opportunities 又决定着哪些地方能换行。

当我们给文本容器设置 width: min-content 时,我们才能看出 anywherebreak-word 的区别。

overflow-wrap: anywhere 会影响计算最小内容内在尺寸的计算,所以容器的宽度会足够小。

overflow-wrap: anywhere

overflow-wrap: break-word 不会对容器宽度产生影响。

overflow-wrap: break-word

总结

经过上文的介绍,word-breakword-wrap 除了都有 word 好像就没啥容易淆的了。

从用途上来说:

  • word-break 是用来定义 soft wrap opportunities,即哪些地方是能够换行的。
  • word-wrap 是用来解决不可分割文本溢出容器的情况的。

那么文本是否可分割是由什么控制的呢?显然就是 word-break,所以 word-break 的优先级是高于 word-wrap 的。当设置了 word-break: break-all 后,就不存在不可分割文本了,那么 word-wrap 属性自然就无效了。

在我们日常使用中,注意以下几个点可以很容易排除混淆:

首先,使用 overflow-wrap 替代 word-wrap,因为 word-wrapword-break 这两看久了真的容易眼花。

其次,不使用 word-break: break-word,一是它已经不被推荐使用了,就是个历史遗留的坑爹属性;二是太容易和 word-wrap: break-word 混淆了,虽然大多数情况下它们的表现是一样的。

最后,少使用 anywhere,一是目前在 chrome 的表现奇怪;二是 min-content 在平时使用的并不多,它会出现与 break-word 的不同的表现的场景并不多。

所以,我们能用的值就只剩下:

word-break
normal 只有 soft wrap opportunity 能够换行
break-all 任意位置都能够换行(CJK 除外)
keep-all CJK 只会在换行符处换行
overflow-wrap
normal 正常换行
break-word 分割单词以满足换行

在常见的分割过单词的场景,我们需要设置 overflow-wrap: break-word。最后,为什么我要花这么多时间来理清这两规则的关系?

参考


花生杀手
432 声望3 粉丝

人矮就要多修图