CSS 实现单/多行文本的省略号显示

工作中需要对后端返回的商品展示数据做处理时用到,对不确定到底多少行时可用伪元素处理

单行文本的省略号显示

CSS3 text-overflow属性

  • CSS3text-overflow属性可实现单行文本的省略号显示,可参考例子
    1
    2
    3
    4
    5
    6
    7
    8
    .singleLineEllipsis{
    // 让容器内多行文字不换行,在一行内显示
    white-space: nowrap;
    // 隐藏溢出部分
    overflow: hidden;
    // 省略号显示
    text-overflow: ellipsis;
    }
  • text-overflow属性指定当文本溢出包含它的元素,应该发生什么
    • 注意:运用于单行文本时,该属性需要搭配以下两个属性使用:
      1
      2
      3
      4
      /* 让容器内多行文字不换行,在一行内显示 */
      white-space: nowrap;
      /* 隐藏溢出部分 */
      overflow: hidden;

多行文本的省略号显示

确定行数

-webkit-line-clamp属性

1
2
3
4
5
6
7
8
9
10
/*将对象作为弹性伸缩盒子模型*/
display: -webkit-box
/*设置或检索伸缩盒对象的子元素的排列方式,默认水平*/
-webkit-box-orient:vertical
/*设置显示多少行*/
-webkit-line-clamp:3
/*元素内容溢出的部分隐藏*/
overflow:hidden
/*当文本溢出包含它的元素,显示省略号“…”*/
text-overflow: ellipsis;

效果

  • -webkit-line-clamp显示的文本的行数。为了实现该效果,需要组合其他的WebKit属性
    1. display: -webkit-box:必须结合的属性 ,将对象作为弹性盒子模型显示 。
    2. -webkit-box-orient:必须结合的属性 ,设置对象的子元素的排列方式 。
  • 注意:
    • -webkit-line-clamp 是一个非标准属性,只能在WebKit内核的浏览器中使用,例如Safari和Chrome。要在其他浏览器中实现相同的效果,可以考虑使用CSS的伪元素或JavaScript来实现。
    • 如果我有4行,但是设置-webkit-line-clamp: 3; ,结果第4行还是显示,只是在第3行末尾出现省略号,如果不确定行数时想实现在最后一行末尾省略号的效果可使用伪元素/js

不确定行数

伪元素

  • 注意,这种方法只能在固定宽度的元素中使用,因为省略号元素的宽度是固定的。如果要在可变宽度的元素中使用,可以使用 JavaScript 或者其他技术实现。
  • 此外,这种方法只适用于使用单一字体的元素,因为不同字体的字符宽度可能会不同,可能导致省略号元素的位置不准确。
    1
    <div class="test">This is some long text that will not fit in the box</div>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    .textContainer {
    /* 设置溢出隐藏 */
    overflow: hidden;
    border: 1px solid #000000;
    /* 设置宽高,超出部分不显示 */
    width: 80px;
    height: 40px;
    /* 子绝父相做个省略号伪元素 */
    position: relative;
    /* 使用伪元素实现最后一行末尾省略号 */
    &::after {
    content: "...";
    position: absolute;
    right: 0;
    bottom: 0;
    width: 1em; /* 留出空隙,不能用padding-left,那样加上...的宽度就多出来了 */
    background-color: white; /* 遮盖原文本 */
    }
    }
  • 在上面的示例中,首先按照之前的方法设置文本溢出省略号。然后,使用 position: relative 属性将元素设置为相对定位。
  • 接着,使用 &::after 伪元素在元素的末尾添加省略号。通过 content 属性设置省略号的文本内容,然后使用 position: absolute 属性将伪元素设置为绝对定位。最后,使用 right: 0bottom: 0 属性将伪元素定位在元素的右下角,并使用 padding-left 属性留出一定的空隙,避免省略号与文本重叠。
  • 为了遮盖原文本,使用 background-color: white 属性将伪元素的背景色设置为白色。
  • 请注意,由于使用了伪元素,所以在实现时需要将样式应用于元素的父元素或者容器元素上,而不是直接应用于文本元素。

js(疯狂循环)

  • 这个做法基本是把容器内可放的所有文字都循环了一边,虽然网上有二分处理,但还可能会出现空白太多的问题,目前我都是直接让后端返回显示的数量或者直接用单行省略号(二分处理可参考
  • 通过测量文本高度并截取文本来实现。具体步骤如下:
    • 确定要设置多行文字省略号的元素。
    • 获取目标元素的高度和行高,并计算出目标元素可以显示的文本行数。
    • 获取元素的文本内容,并根据元素高度和行高计算出需要显示的文本内容。
    • 在该元素的内容末尾添加省略号。
1
2
3
<div class="textContainer">
平台退换货状态退换货原因收货入仓状态收货入仓时间创建时间申请时间(买家在平台申请退换货的时间)
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
addEl() {
const target = document.querySelector('.textContainer'); // 获取目标元素
const lineHeight = parseInt(window.getComputedStyle(target).lineHeight); // 获取目标元素的行高
const height = parseInt(window.getComputedStyle(target).height); // 获取目标元素的高度
const lines = Math.floor(height / lineHeight); // 计算目标元素可以显示的最大行数【Math.floor返回小于等于参数的最大整数】
const content = target.textContent.trim(); // 获取目标元素的文本内容,去除首尾空白

if (content.length > 0) {
if(target.scrollHeight <= height) { // 不需要省略号
return
}
const arrContent = content.split(''); // 将文本转换为数组,方便删掉末尾的字符给省略号留位置!
let truncated = false; // 标记是否需要省略号

// 初始4个字(1行1个字)作为测试文本,每次循环+1字,从少到多测试到目标元素最多能塞多少文字【疯狂循环,性能肯定不咋地,但是实现效果很好】
for (let i = lines; i < arrContent.length; i++) {
target.textContent = arrContent.slice(0, i).join(''); // 更新元素的文本内容【用target元素显示部分文字作为测试文本试试会不会填满目标元素】
if (target.scrollHeight > height) { // 如果文本高度超过目标元素高度,则说明需要省略号
target.textContent = arrContent.slice(0, i - 3).join('') + '...'; // 在文本末尾添加省略号
truncated = true;
break; // 循环到测试文本能填满容器可视高度的最后一行就作为文本末尾,剩下的不塞进target.textContent,不然省略号位置会出现在文本末尾,但不在可视范围
}
}
}
},