·  阅读

最近面试的时候被问到通常文本省略和文本换行怎么去处理,菜鸟的我下意识就说文本省略的话设置 text-overflow 属性值为 ellipsis ,文本换行的话通过设置 word-break 属性来处理。话音刚落,面试官沉默了一下,显然对我的回答不太满意。然后又问我什么情况下 text-overflow 什么情况下会失效呢?我说,文本换行了就失效了。接着面试官又问,那么在换行的情况下,又如何去处理呢?emmmm......

对此,也是来深入了解下与文本省略和文本换行相关的这些属性。

由于 text-overflow 在某些情况下会失效,需要配合某些属性一起使用,所以先来看看与文本换行的一些属性。

一、文本换行(white-space、word-break、overflow)

1.1 white-space

white-space 顾名思义,就是空白,严格来说该属性是用来设置 如何处理元素中的空白 的。

该属性有如下取值:

属性值 描述
normal (默认值) 连续的空白符会被 合并 ,换行符会被当作空白符来处理
nowrap 连续的空白符会被合并。但 文本内的换行无效
pre 连续的空白符会被 保留 。在遇到换行符或者 <br> 元素时才会换行。(preserve)
pre-wrap 连续的空白符会被 保留 。在遇到换行符或者 <br> 元素,或者需要为了填充时才会换行。
pre-line 连续的空白符会被 合并 。在遇到换行符或者 <br> 元素,或者需要为了填充时会换行。

下面就基于以下HTML结构来详细了解下每个属性值的作用

<style>
    .text {
        margin: 50px
    .text {
        width: 100px;
        height: 200px;
        border: 1px solid black;
</style>
<div class="text">
    这是一段测试文本      空白后的文本
    第二行文本<br/>换行标签后文本
    Third Line LongTextaaaaaaaa
</div>

(1)normal

noraml 是默认值,表示连续的空白字符会被合并,换行符也会被当作空白符处理。

white-space: normal;

如图所示,“这是一段测试文本 空白后的文本” 之间的空白符被合并成了,而且每一行的换行符也是当作空白符来处理了。但是 <br/> 换行标签和通过&nbsp定义的空格不会受到影响。

(2)nowrap

nowrap,顾名思义,就是不换行。即:连续的空白字符会被合并,但是文本内的换行无效。

white-space: nowrap

如下图所示,与normal的主要区别在于,当文本到达盒子边界时,文本不会自动换行。但是遇到<br/>标签仍然会换行。

(3)pre

pre其实是单词 preserve(保留) 的缩写,这样一来就比较容易理解了。即:连续的空白符会被保留。在遇到换行符或者<br>元素时才会换行

white-space: pre

如图所示,所有的空白字符都保留了,而且文本遇到换行符时会换行,不会当作空白字符处理。当文本到达盒子边界时并不会自动换行。

(4)pre-wrap

pre-wrap可以理解为 pre + wrap,与 pre 不同的在于当文本到达盒子边界时会自动换行。

white-space: pre-wrap

(5)pre-line

pre-linepre-wrap 不同的在于,pre-line 会合并空白字符。(需要注意的是,pre-line 也不会将换行符当作空白符处理)

white-space: pre-line

其实还有个break-space属性,但是需要比较高版本的浏览器才能兼容,所以暂且引用MDN上的一段介绍:

break-spaces 与 pre-wrap的行为相同,除了:

  • 任何保留的空白序列总是占用空间,包括在行尾。
  • 每个保留的空格字符后都存在换行机会,包括空格字符之间。
  • 这样保留的空间占用空间而不会挂起,从而影响盒子的固有尺寸(最小内容大小和最大内容大小)。
  • white-space 不同值的行为总结如下:

    换行符空格和制表符文字换行行尾空格
    normal合并合并换行删除
    nowrap合并合并不换行删除
    pre保留保留不换行保留
    pre-wrap保留保留换行挂起
    pre-line保留合并换行删除
    break-spaces保留保留换行换行

    有关什么时候文本会自动换行,可参考该文档:www.w3.org/TR/CSS2/vis…

    1.2 word-break

    1.1 中的 white-space 主要是对空白字符的处理,遇到换行符时如何处理,以及文本到达边界时是否自动换行等。 那么接下来的 word-break 属性就是用于指定怎样在单词内断行

    word-break 属性的值如下所示:

    属性值描述
    normal(默认值)使用默认的断行规则
    break-all对于 non-CJK (CJK 指中文/日文/韩文) 文本,可在任意字符间断行
    keep-allCJK 文本不断行。Non-CJK 文本表现同 normal
    break-word在空格处断行(已弃用)

    那么基于下面代码来详细了解一下word-break

    (1)normal

    默认值,使用默认的断行规则。

    (2)keep-all

    CJK 文本不断行。Non-CJK 文本表现同 normal

    word-break: keep-all
    

    如下图所示,中文和日语文本都没有断行,但是遇到空格会断行。可以理解为保持所有单词不拆分,因此连续的 CJK 文本也会被当作一个单词,不会被拆分。或者也可以理解为,遇到空格才会换行

    (3)break-all

    break-all:不论什么语言,只要文本碰到边界就换行。对于英文,会从单词中间将单词断开。

    word-break: break-all
    

    (4)break-word

    break-word:其实就是对于CJK 文本遇到边界就换行,而非CJK 文本,只有遇到单行放不下的单词时会分割。

    word-break: break-word
    

    1.3 overflow-wrap

    overflow-wrap是用来说明当一个不能被分开的字符串太长而不能填充其包裹盒时,为防止其溢出,浏览器是否允许这样的单词中断换行。是由 word-wrap 属性转换而来。

    word-wrap 属性原本属于微软的一个私有属性,在 CSS3 现在的文本规范草案中已经被重名为 overflow-wrap 。 word-wrap 现在被当作 overflow-wrap 的 “别名”。 稳定的谷歌 Chrome 和 Opera 浏览器版本支持这种新语法。

    overflow-wrap 属性值如下所示:

    属性值描述
    normal行只能在正常的单词断点处中断(例如两个单词之间的空格)
    break-word表示如果行内没有多余的地方容纳该单词到结尾,则那些正常的不能被分割的单词会被强制分割换行。

    (1)normal

    在正常单词断点处中断

    overflow-wrap: normal
    

    (2)break-word

    当某个很长的单词到达边界时,会被强制分割。(该属性常会用到)

    overflow-wrap: break-word
    

    二、文本省略(text-overflow)

    text-overflow 属性用于确定如何提示用户存在隐藏的溢出内容。其形式可以是裁剪、显示一个省略号(“”)或显示一个自定义字符串。

    text-overflow 属性可能被赋予一个或者两个值。

  • 如果赋一个值,指的行末溢出行为(从左至右的文本右末端,从右至左的文本左末端)。
  • 如果赋两个值,第一个值指定行左端溢出行为,第二个值指定行右端溢出行为。
  • text-overflow 属性的值如下所示,

    属性值描述
    clip默认值,这个关键字会在内容区域的极限处截断文本,因此可能会在单词的中间发生截断
    ellipsis这个关键字会用一个省略号('…')来表示被截断的文本。这个省略号被添加在内容区域中,因此会减少显示的文本。如果空间太小以至于连省略号都容纳不下,那么这个省略号也会被截断。
    string用来表示被截断的文本(实验阶段)
  • ellipsis
  • 有关文本溢出处理,本文主要关注两点

    (1)text-overflow 什么时候生效

    text-overflow 只有在单行文本超过边界的时候设置才会生效,所以必须配合以下两个属性一起使用。

    white-space: nowrap;
    overflow-x: hidden;
    

    (2)如果是多行文本,那么如果进行文本省略呢?

    有关这个问题,也是参考一位大佬的想法。

    既然text-overflow只能用于单行文本的情况,那么多行文本的时候当然就失效了。其实我们可以:

  • 首先获取内容区域的宽度
  • 然后计算内容区文本的总长度
  • 将文本总长度除以内容区域宽度,预估文本需要多少行
  • 然后自定义每一行放置哪些文本(即如何分割文本)
  • 自定义要显示的行数,然后在最后一行对省略符号(自定义)进行拼接
  • 这样也就实现多行文本的省略。

    因为是大佬的想法,这里就不贴代码了,提供一个思路供大家参考。或许还有更好的方法,也欢迎大家交流。

    好了,本文到这就结束啦!