跳至主要內容

文本溢出

大约 6 分钟

文本溢出截断省略

文本溢出截断省略是比较常见的业务场景,主要分为单行文本溢出截断省略与多行文本溢出截断省略,单行的截断方案比较简单,多行截断相对比较复杂。

单行溢出省略

单行文本溢出截断省略直接使用CSS即可,其无兼容问题,文本溢出范围才显示省略号,否则不显示省略号,省略号位置显示刚好,但是只能作为单行文本溢出截断省略的解决方案。

一行文本溢出省略
<section class='box'>
  <div class="t1">很长很长很长很长很长很长很长很长的文本</div>
  <div class="t1">不很长的文本</div>
</section>
.box{
    width: 100px;
}
.t1 {
  width: 120px;
  white-space: nowrap; /* 文字在一行显示不能换行 */
  overflow: hidden; /* 文字长度超出限定宽度则截断 */
  text-overflow: ellipsis; /* 文本溢出时显示省略符号 */
}

多行溢出省略

按行计算 CSS 方案

多行文本溢出截断省略按行计算使用CSS,其文本溢出范围才显示省略号,否则不显示省略号,省略号位置显示刚好,但是兼容性一般,line-clamp属性只有WebKit内核的浏览器才支持,多适用于移动端页面,因为移动设备浏览器更多是基于WebKit内核。

按字计算 CSS 方案
<section class='box'>
  <div class="t2">不很长的文本</div>
  <div class="t2">
    很长很长很长很长很长很长很长很长的很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的文本
  </div>
</section>
.box{
    width: 100px;
}
.t2 {
  -webkit-line-clamp: 3; /* 限制在一个块元素显示的文本的行数 兼容性 https://caniuse.com/#search=line-clamp */
  display: -webkit-box; /* 显示为弹性伸缩盒子模型 */
  box-orient: vertical; /* 设置伸缩盒对象的子元素的排列方式 */
  overflow: hidden; /* 文字长度超出限定宽度则截断 */
  text-overflow: ellipsis; /* 文本溢出时显示省略符号 */
}

按行计算 Js 方案

多行文本溢出截断省略按行计算使用Js,其无兼容问题,文本溢出范围才显示省略号,否则不显示省略号,但是需要Js实现,背离展示和行为相分离原则,文本为中英文混合时,省略号显示位置略有偏差。

按行计算 Js 方案
<section class='box '>
  <div class="t3">不很长的文本</div>
  <div class="t3">
    很长很长很长很长很长很长很长很长的很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的文本
  </div>
</section>
.box{
    width: 100px;
}
 (function () {
    var lineNum = 3;
    var elements = document.getElementsByClassName("t3");
    Array.prototype.forEach.call(elements, (element) => {
      var text = element.innerText;
      var textLen = text.length;
      var baseWidth = window.getComputedStyle(element).width;
      var fontsize = window.getComputedStyle(element).fontSize;
      var lineWidth = baseWidth.slice(0, -2);
      var charCount = Math.floor(lineWidth / fontsize.slice(0, -2)); // 计算一行内可容纳字数
      var content = "";
      var totalStrNum = Math.floor(charCount * lineNum); // 多行可容纳总字数
      var lastIndex = totalStrNum - textLen;
      if (textLen > totalStrNum)
        content = text.slice(0, lastIndex - 3).concat("...");
      else content = text;
      element.innerText = content;
    });
  })();

按高度计算 CSS 方案

多行文本溢出截断省略按高度计算使用CSS,利用Float的浮动,通过::before::after两个伪元素实现浮动操作,其无兼容问题,文本溢出范围才显示省略号,否则不显示省略号,但省略号显示可能不会刚刚好,有时会遮住一半文字。

按高度计算 CSS 方案
<section>
  <div class="t4">
    <div class="text">不很长的文本</div>
  </div>
  <div class="t4">
    <div class="text">
      很长很长很长很长很长很长很长很长的很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的文本
    </div>
  </div>
</section>
  .t4 {
    max-height: 40px;
    line-height: 20px;
    overflow: hidden;
  }
  .t4::before {
    float: left;
    content: "";
    width: 20px;
    height: 40px;
  }
  .t4 .text {
    float: right;
    width: 100%;
    margin-left: -20px;
    word-break: break-all;
  }
  .t4::after {
    float: right;
    background-color: #fff;
    content: "...";
    width: 20px;
    height: 20px;
    position: relative;
    left: 100%;
    transform: translate(-100%, -100%);
  }

代码示例

<!DOCTYPE html>
<html>
  <head>
    <title>文本溢出截断省略</title>
    <style type="text/css">
      #container {
        width: 300px;
        border: 1px solid #eee;
        position: relative;
      }
      section {
        padding: 5px 0;
        margin: 5px;
        border-bottom: 1px solid #eee;
      }
      .t1 {
        white-space: nowrap; /* 文字在一行显示不能换行 */
        overflow: hidden; /* 文字长度超出限定宽度则截断 */
        text-overflow: ellipsis; /* 文本溢出时显示省略符号 */
      }
      .t2 {
        -webkit-line-clamp: 3; /* 限制在一个块元素显示的文本的行数 */
        display: -webkit-box; /* 显示为弹性伸缩盒子模型 */
        -webkit-box-orient: vertical; /* 设置伸缩盒对象的子元素的排列方式 */
        overflow: hidden; /* 文字长度超出限定宽度则截断 */
        text-overflow: ellipsis; /* 文本溢出时显示省略符号 */
      }
      .t4 {
        max-height: 40px;
        line-height: 20px;
        overflow: hidden;
      }
      .t4::before {
        float: left;
        content: "";
        width: 20px;
        height: 40px;
      }
      .t4 .text {
        float: right;
        width: 100%;
        margin-left: -20px;
        word-break: break-all;
      }
      .t4::after {
        float: right;
        background-color: #fff;
        content: "...";
        width: 20px;
        height: 20px;
        position: relative;
        left: 100%;
        transform: translate(-100%, -100%);
      }
    </style>
  </head>
  <body>
    <div id="container">
      <section>
        <div class="t1">不很长的文本</div>
        <div class="t1">很长很长很长很长很长很长很长很长的文本</div>
      </section>

      <section>
        <div class="t2">不很长的文本</div>
        <div class="t2">
          很长很长很长很长很长很长很长很长的很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的文本
        </div>
      </section>

      <section>
        <div class="t3">不很长的文本</div>
        <div class="t3">
          很长很长很长很长很长很长很长很长的很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的文本
        </div>
      </section>

      <section>
        <div class="t4">
          <div class="text">不很长的文本</div>
        </div>
        <div class="t4">
          <div class="text">
            很长很长很长很长很长很长很长很长的很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的文本
          </div>
        </div>
      </section>
    </div>
  </body>
  <script type="text/javascript">
    (function () {
      var lineNum = 3;
      var elements = document.getElementsByClassName("t3");
      Array.prototype.forEach.call(elements, (element) => {
        var text = element.innerText;
        var textLen = text.length;
        var baseWidth = window.getComputedStyle(element).width;
        var fontsize = window.getComputedStyle(element).fontSize;
        var lineWidth = baseWidth.slice(0, -2);
        var charCount = Math.floor(lineWidth / fontsize.slice(0, -2)); // 计算一行内可容纳字数
        var content = "";
        var totalStrNum = Math.floor(charCount * lineNum); // 多行可容纳总字数
        var lastIndex = totalStrNum - textLen;
        if (textLen > totalStrNum)
          content = text.slice(0, lastIndex - 3).concat("...");
        else content = text;
        element.innerText = content;
      });
    })();
  </script>
</html>

注:

  1. -webkit-line-clamp 用来限制在一个块元素显示的文本的行数。 为了实现该效果,它需要组合其他的 WebKit 属性。常见结合属性:
  2. display: -webkit-box; 必须结合的属性 ,将对象作为弹性伸缩盒子模型显示 。
  3. -webkit-box-orient 必须结合的属性 ,设置或检索伸缩盒对象的子元素的排列方式 。