CSS 解决多行省略的方案有很多种,本篇过滤了一些仅适用于一定会出现省略的情况,主要针对项目中比较常见的不确定行数的情况整理了 4 种方法,并且梳理了在什么情况下建议选择哪个方案。
需要兼容 PC 不?
“...” 就好还是需要自定义?
“...” 带渐变遮罩 OK 吗?
需要自适应高度吗?
问完这四个问题,选择一个方案。
方案 1:最简单的 -webkit-line-clamp
在线地址:-webkit-line-clamp
优点:
- 简单易用,马上上手
- 自适应高度
缺点:
- 省略符不能自定义
- 需要 PC 兼容就血崩,比较适合移动端
.ell-multi(@line: 2) {
display: -webkit-box;
-webkit-line-clamp: @line;
-webkit-box-orient: vertical;
overflow: hidden;
}
方案 2:很有想法的 float
在线地址:很有想法的float
优点:
- 兼容性强,全世界都支持 float
- 省略符拓展性强,想怎么搞就怎么搞
缺点:
- 不能自适应高度,会被设计师打
- 第一次用需要认真理解一下原理,很难受
- 省略符需要带底色,不适合背景复杂的区域,会穿帮
下面就针对第二个缺点,把实现过程解释一下,避免下次还难受。
1、层级很简单,一个盒子中有三个元素。我们先给三个元素都加上浮动,并且通过颜色看看这三个元素的位置。
<div class="ell-box">
<div class="ell-box__text">CSS自定义属性?听着怎么那么神奇呢,属性还可以自定义,那不是可以放肆地玩耍?我自己定义的属性浏览器都能认识?CSS自定义属性?听着怎么那么神奇呢,属性还可以自定义,那不是可以放肆地玩耍?我自己定义的属性浏览器都能认识?</div>
<div class="ell-box__placeholder"></div>
<div class="ell-box__more">...展开</div>
</div>
/* 包裹层 */
.ell-box {
position: relative;
width: 400px;
/* 确定高度 */
height: 60px;
/* 为了方便看暂时不 overflow: hidden */
}
.ell-box__text {
float: right;
font-size: 14px;
line-height: 20px;
width: 100%;
background-color: rgba(255, 244, 94, 0.5);
/* 黄色 */
}
.ell-box__placeholder {
float: right;
width: 60px;
/* 等于包裹层高度 */
height: 60px;
background-color: rgba(243, 33, 33, 0.54);
/* 红色 */
}
.ell-box__more {
float: right;
width: 60px;
height: 20px;
line-height: 20px;
text-align: right;
font-size: 14px;
background-color: rgba(40, 62, 233, 0.5);
/* 紫色 */
}
2、上面的表现符合我们的预期,黄色、红色、紫色块依次从右边开始排布,现在我们调整一下位置。
/* more 和 placehoder 的宽度为 60px */
.ell-box__text {
margin-left: -60px;
}
当黄色
有 margin-left 之后,就给了 红色
空间,可以排在一排。
当 黄色
的高度小于 红色
的高度时,例如文字显示 2 行,此时第一排的高度为 红色
的高度,所以排在后面的 紫色
不能挤进第一排,只能屈居第二排。
当 黄色
的高度大于 红色
的高度时,例如文字显示 4 行,此时第一排的高度被 黄色
的高度撑开,所以排在后面的 紫色
就能挤进所谓的和 黄色
同排。
3、也就是说当 黄色
需要省略 or 不需要省略的时候,紫色
的位置是不一定的。这样我们就有操作的空间了,嘿嘿嘿。
.ell-box__more {
position: relative;
/* 距离左边宽度 100% 的距离 */
left: 100%;
/* 再往左往上回 */
transform: translate(-100%, -100%);
}
4、最后修饰一下,加上隐藏和渐变背景(参考页面背景色)。
.ell-box {
overlfow: hidden;
}
.ell-box__more {
background-image: linear-gradient(270deg, #FFFFFF 48%, rgba(255, 255, 255, 0.87) 74%, rgba(255, 255, 255, 0) 100%);
}
方案 3: 自适应高度的 float
上面的 float
方案其实挺好的,但是很多时候 我们 设计师有自适应高度的需求,该怎么办呢?
这里的矛盾点在于,省略符的展示魔法需要定高,而自适应高度则不能定高,看起来水火不容。
这里提供一种思路:需要渲染两份文案,其中,真实展示的文案自由撑开高度,外层仅限制最大高度,这样就满足自适应高度的需求,而省略符的展示需要一个定高的绝对定位区域来辅助。
实现的效果还是不错的,但是多渲染了一份文案,总感觉还不是很完美,欢迎大家提出更好的想法~
<div class="ell-box">
<!-- 真实展示的文案 -->
<div class="ell-box__text">CSS自定义属性?听着怎么那么神奇呢,属性还可以自定义,那不是可以放肆地玩耍?我自己定义的属性浏览器都能认识?CSS自定义属性??</div>
<!-- 用于撑开高度展示“more"的文案 -->
<div class="ell-box__abs">
<div class="ell-box__text">CSS自定义属性?听着怎么那么神奇呢,属性还可以自定义,那不是可以放肆地玩耍?我自己定义的属性浏览器都能认识?CSS自定义属性??</div>
<div class="ell-box__placeholder"></div>
<div class="ell-box__more">...展开</div>
</div>
</div>
/* 核心修改 */
.ell-box {
/* 包裹层改为自动高度,仅设置最大高度 */
max-height: 60px;
overflow: hidden;
}
.ell-box__abs {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 60px;
}
.ell-box__abs ..ell-box__text {
color: transparent;
}
在线地址:自适应高度的float
对比方案 2,优点就是可以自适应高度,但是缺点也很突出,就是需要多渲染一份不可见的文案。
方案 4:魔法升级的 float
+ -webkit-line-clamp
如果设计师接受不了渐变的处理,或者该区域的背景颜色复杂的话,那么可以尝试一下下面这个结合方案,给你一个截断+透明的自定义省略符。
在线地址:魔法升级的float+-webkit-line-clamp
这个效果基于CSS的多行省略中的方案进行优化,因为在学习的过程中发现原来的方案有一定的问题(使用-webkit-line-clamp
的元素无法撑开完整高度),导致无法实现上述效果。
现在看看改进后的方案:
<div class="ell-box">
<!-- 展示部分 -->
<div class="ell-box__text">
<div class="ell-box__inner inline">CSS自定义属性?听着怎么那么神奇呢,属性还可以自定义,那不是可以放肆地玩耍?我自己定义的属性浏览器都能认识?CSS自定义属性??
</div>
</div>
<!-- 自定义省略符展示部分 -->
<div class="ell-box__fake">
<div class="ell-box__inner fake">CSS自定义属性?听着怎么那么神奇呢,属性还可以自定义,那不是可以放肆地玩耍?我自己定义的属性浏览器都能认识?CSS自定义属性??</div>
<div class="ell-box__abs">
<div class="ell-box__placeholder"></div>
<div class="ell-box__more">... [详情]</div>
</div>
</div>
</div>
划重点啦!! 这个方案虽然稍显复杂,但是只要理解了两个点就可以实现了,两个点分别是上述两个部分。
我们先看第一部分,这部分要实现的效果是,展示文案中给自定义省略的地方空出位置。
.ell-box__text {
display: -webkit-box; /* 设置 3 行省略 */
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
font-size: 50px; /* 设置省略号的字号,也就是我们自定义省略符的宽度 */
line-height: 0; /* 重置一些参数 */
letter-spacing: 0; /* 重置一些参数 */
color: transparent; /* 原来的省略号不显示 */
color: read; /* 用做实验,我们先设置为红色 */
}
.ell-box__inner {
/* 重置正常显示的文案字号/颜色等等 */
font-size: 14px;
line-height: 20px;
color: #000;
vertical-align: top;
letter-spacing: 0;
}
.ell-box__inner.inline {
display: inline;
}
这里为了更好理解,先把省略号颜色设置为红色,而文字包裹层的字号则为省略号所占的宽度,所以只要把省略号设置为透明色,我们就给自定义省略留出了空位。
继续看第二部分,这部分要实现的效果是,让自定义省略符放在预期位置,这里利用的也是float
的原理。
这一部分也是绝对定位的元素,内部文案撑开高度,然后再嵌一层绝对定位的元素,left: 50%
。第二层内元素即为蓝色、红色、紫色块依次 float: right
的布局,当蓝色块的高度随着文案被撑开到大于 3 行的高度时,紫色块就会排到展示区域的右下角。
再把自定义省略符的紫色块向上挪一下位置就完美了。
最后把伪装的文字设置为透明,两部分结合起来就是上面的效果啦。
体验小优化
1、无论是 float
方案还是结合方案,自定义的省略符一般都是靠右对齐的,那么多行省略的文案最好也能靠边对齐,视觉上会比较整齐。
.text {
text-align: justify;
}
2、如果内容含有英文的话,英文单词换行也会导致视觉不对齐,可以考虑单词内换行,但是可读性也会下降,就看个人需求啦。
.text {
word-break: break-all;
}
在线地址:demo
最后简单带一下单行省略
.single-line-ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
总结
序号 | 方案 | 优点 | 缺点 |
---|---|---|---|
1 | -webkit-line-clamp | 简单易用 / 自适应高度 | 不兼容 PC ie |
2 | float | 兼容性好 / 可自定义 | 定高 / 省略符带渐变背景 |
3 | float + 两份文案 | 可自定义 / 自适应高度 | 省略符带渐变背景 |
4 | float + -wekit-line-clamp + 两份文案 | 可自定义 / 自适应高度 / 省略符背景透明 | 不兼容 PC ie |