前言
CSS的学习,就我个人看来,是有别于JavaScript这张传统程序语言的学习的。本身属性就多,值也多,不同属性在一起表现也不一样,不同属性和不同类型的HTML标签在一起又不一样,再加上兼容性差异和未定义行为。就像是很多个不确定因素,有着无穷多的组合和可能性。掌握这些不确定性,看书是绝对不够的,一定是要多多实践,多多思考,多多积累。对于底层机理的理解,也是需要一定的天赋的。
因此,就是自己很多年一直与CSS密切打交道,学习它,也有很多不知道的,理解不透彻,或者说因为要学习和思考的东西太多,还来不及估计到一些属性或者声明。
比方说本文要介绍的word-break:break-all和word-wrap:break-word, 虽然都有使用,都照过面,实际上,却一直没有机会能够好好看看这两个到底有什么区别,各个浏览器的兼容性如何,等等。换句话说,就是深入理解。
背景
做移动端项目时,在详情页富文本传过来一段很长的空格;页面展示的时候由于空格没有及时换行;导致空格后文字超出屏幕;页面展示缺少文字。当然,这个情况有兼容性,就是大部分的安卓手机;同样的在PC端(小屏幕)展示同样有问题;我的14.7寸的展示就有问题;
word-break属性
- 属性值:
normal;
使用默认的换行规则。(即单词中间不换行,会提前折行);(会溢出)
break-all;
允许任意非CJK(Chinese/Japanese/Korean)文本间的单词断行。
一个长长的单词不会新起一行展示,而是直接在本行剩余空间展示,展示不全时折断展示;(万恶原则)
兼容性:所有浏览器都支持;
keep-all;
不允许CJK(Chinese/Japanese/Korean)文本中的单词换行,只能在半角空格或连字符处换行。非CJK文本的行为实际上和normal一致。(会溢出)
break-word;
一个长长的单词会新起一行展示,新的一行展示不全时折断展示;(新人榨干原则)
万恶原则:不会新起一行,而是在本行剩余空间继续展示,不够则打断折行。能利用每一行的剩余空间,不浪费一点点空间;我这里将这样的‘不留余地’称作万恶的压榨原则;
新人榨干原则:本行不够展示的时候,会另起新的一行展示,如果在新的一行上仍然不够的话,会打断折行展示;这种新起一行,不利用上一行的剩余空间原则;我称之为新人榨干原则;
兼容性:
word-wrap 属性
normal;
正常的换行规则(长单词新起一行且不折断)(会溢出)
bredak-word;
一个长长的单词会新起一行展示,且在新的一行展示不全时折断展示;(新人榨干原则)
word-wrap属性其实也是很有故事的,之前由于和word-break长得太像,难免会让人记不住搞混淆,晕头转向,于是在CSS3规范里,把这个属性的名称给改了,叫做:overflow-wrap 这个新属性名称显然语义更准确,也更容易区别和记忆。
但是呢,也就Chrome/Safari等WebKit/Blink浏览器支持。
所以,虽然换了个好看好用的新名字,为了兼容使用,目前,还是乖乖使用word-wrap吧。兼容性见下表(黄绿色的表示不支持overflow-wrap新的标准属性的):
overflow-wrap属性 (word-wrap的别名)
- 是用来说明当一个不能被分开的字符串太长而不能填充其包裹盒时,为防止其溢出,浏览器是否允许这样的单词中断换行。
- 与word-break相比,overflow-wrap仅在无法实现-将整个单词放在自己的行而不溢出的情况下,才会产生中断。
- 属性值:
normal;
行只能在正常的单词断点处中断。(会溢出)。
anywhere;
允许任意非CJK(Chinese/Japanese/Korean)文本间的单词断行。(一个单词一行;长单词截断)
兼容性:所有浏览器都支持
break-word;
表示如果行内没有多余的地方容纳该单词到结尾,则那些正常的不能被分割的单词会被强制分割换行(新人榨干原则)。
- 兼容性:
white-space属性
- 属性值:
white-space CSS 属性是用来设置如何处理元素中的空白;
normal
连续的空白符会被合并,换行符会被当作空白符来处理。换行在填充「行框盒子(line boxes)」时是必要。
nowrap
和 normal 一样,连续的空白符会被合并。但文本内的换行无效
pre
连续的空白符会被保留。在遇到换行符或者
元素时才会换行。
pre-wrap
连续的空白符会被保留。在遇到换行符或者
元素,或者需要为了填充「行框盒子(line boxes)」时才会换行。
pre-line
连续的空白符会被合并。在遇到换行符或者
元素,或者需要为了填充「行框盒子(line boxes)」时会换行。
break-spaces
与 pre-wrap的行为相同,除了:
任何保留的空白序列总是占用空间,包括在行尾。
每个保留的空格字符后都存在换行机会,包括空格字符之间。
这样保留的空间占用空间而不会挂起,从而影响盒子的固有尺寸(最小内容大小和最大内容大小)。
兼容性:
line-break属性
- 属性值:
用来处理如何断开(break lines)带有标点符号的中文、日文或韩文(CJK)文本的行。
auto
使用默认的断行规则分解文本。
loose
使用尽可能松散(least restrictive)的断行规则分解文本。一般用于短行的情况,如报纸。
normal
使用最一般(common)的断行规则分解文本。
strict
使用最严格(stringent)的断行原则分解文本。
anywhere
在每个印刷字符单元(typographic character unit)的周围,都有一个自动换行(soft wrap)的机会,包括任何标点符号(punctuation character)或是保留的空白字符(preserved white spaces),或是单词之间。但忽略任何用于阻止换行的字符,即使是来自 GL、WJ 或 ZWJ 字符集的字符,或是由 word-break 属性强制的字符。不同的换行机会拥有相同的优先级。也不应用断字符(hyphenation,可能是 “-“)。
- 兼容性:
火狐浏览器不支持此属性;其余浏览器均支持
我遇到的棘手问题
问题描述:
在一段富文本中;有很多空格,导致这些空格联为一体,不能折行,直到遇见第一个字符才折行;导致文本溢出;
复现条件:
部分安卓手机(oppo)
京东app(非极速版)
两个条件缺一不可,因为尝试了在有问题的手机,自带和qq浏览器时,是没有问题的;同时极速版的京东app也是没有问题的;富文本结构如下:
1
2
3
4
5
6
7
8<p>
<span> </span><span> </span><span> </span>...很多个空白span标签
<span> </span>
<span>
<span> </span><span>我是要展示的文本</span>
</span>
</p>尝试属性:white-space;这个属性的合并空格在此处是不生效的;因为文本的空格是由多个span标签分割的;本身就不属于连续空格;所以合并空格不起作用;
尝试属性:line-break;1
2let text = "<p style='text-align: right; line-height: 22px; text-indent: 24px; margin-top: 0px; margin-right: 21px; margin-bottom: 0px;'><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'> </span><span style='font-family:;'> </span><span style='font-family:宋体'><span style='font-family:;'> </span><span style='color: rgb(0, 0, 0); font-size: 21px;'>邵武市人民法院</span></span></p>";
可能的解决方案
解决方案一:
将富文本的父盒子元素设置为font-size:0;可以解决这个问题;但是存在风险,一旦文字未设置字体,则继承字体为0;文字就会不展示;所以弃用该方案;
解决方案二:
使用正则将空格的span标签去掉;
尝试方案:
word-break: break-all;
white-space: pre-line;
line-break: anywhere;–不管用;
最后:
如果谁能帮忙解决此问题,欢迎留言;