愿你坚持不懈,努力进步,进阶成自己理想的人

—— 2017.09, 写给3年后的自己

多行文本溢出解决方案

一、问题场景

在业务开发中,经常会遇到需要控制超长文本的问题。而处理这个问题一般的做法是对其进行截断:传统情况下,我们可以限制字符最多可以有几个字符,然后超出这个阈值后substr并加上省略号。但是这种方案是有局限性的。如果我们的文本显示区域是随着窗口大小变化的,那么固定字符长度的截断方案仍然不美观,所以我们通常使用CSS来进行控制。如:

<div class="box">这是一段超长的文本!!这是一段超长的文本!!这是一段超长的文本!!这是一段超长的文本!!这是一段超长的文本!!这是一段超长的文本!!</div>

其中CSS如下:

.box {
    width: 150px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

这种方案下,会得到如下的显示效果:

这是一段超长的文...

但是问题又来了,如果我想要的是文本超过两行,或者三行甚至更多行后截断呢?那么,这种方案又捉襟见肘了。为了处理这个问题,本文将探讨一些解决的方案

二、使用-webkit-line-clamp

-webkit-line-clamp是面向webkit内核浏览器的一个私有属性,可以很好得实现多行文本溢出问题。它的兼容性如下:

要实现多行文本溢出,需要结合以下的属性进行使用:

  • display: -webkit-box 必须结合的属性,将对象作为弹性伸缩盒子模型显示
  • -webkit-box-orient 必须结合的属性,设置或检索伸缩盒对象的子元素的排列方式
  • text-overflow: ellipsis

完整的示例:

<div class="box">这是一段超长的文本!!这是一段超长的文本!!这是一段超长的文本!!这是一段超长的文本!!这是一段超长的文本!!这是一段超长的文本!!</div>

CSS:

.box {
    width: 150px;
    overflow: hidden;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    text-overflow: ellipsis;
    -webkit-line-clamp: 2;
}


三、兼容多浏览器的方案

-webkit-line-clamp虽好,但是兼容的浏览器情况不佳。为了在更多的浏览器下进行多行文本溢出处理,我们需要有一个跨浏览器的解决方案,其基本思想如下:

  • 使用line-heightheight,且以em为单位控制容器高度
  • 设置文本容器的positionrelative,使用::after添加一个遮罩层来显示溢出效果(IE6-IE7下在末尾加一个span代替)

示例如下:

<div class="box">这是一段超长的文本!!这是一段超长的文本!!这是一段超长的文本!!这是一段超长的文本!!这是一段超长的文本!!这是一段超长的文本!!</div>

CSS:

.box {
    width: 150px;
    position: relative;
    overflow: hidden;
    line-height: 1.5em;
    height: 3em; /* 显示2行 */
}
.box::after {
    content: '...';
    position: absolute; bottom: 0; right: 0;
    padding: 0 20px 0 45px;
    background: url(https://haitao.nos.netease.com/f773ed67-52ae-47a4-989e-647f35edea93.png) repeat-y;
}

但是该方法也有一个很明显的缺点:在文本未超出的情况下,也会显示省略号。为了解决该问题,可以结合JavaScript进行判断来完善

四、参考资料

多行文本溢出显示省略号(…)全攻略