CSS小技巧

可能是最全的 “文本溢出截断省略” 方案合集

2019-12-09  本文已影响0人  兔子不打地鼠打代码

本文首发于政采云前端团队博客:可能是最全的 “文本溢出截断省略” 方案合集

https://www.zoo.team/article/text-overflow

前言

在我们的日常开发工作中,文本溢出截断省略是很常见的一种需考虑的业务场景细节。看上去 “稀松平常” ,但在实现上却有不同的区分,是单行截断还是多行截断?多行的截断判断是基于行数还是基于高度?这些问题之下,都有哪些实现方案?他们之间的差异性和场景适应性又是如何?凡事就怕较真,较真必有成长。本文试图通过编码实践,给出一些答案。

先来点基础的,单行文本溢出省略

******核心 CSS 语句******

******优点******

********短板********

**********适用场景**********

************Demo************

<style>    .demo {        white-space: nowrap;        overflow: hidden;        text-overflow: ellipsis;    }</style><body>    <div class="demo">这是一段很长的文本</div></body>

**************示例图片**************

image

进阶一下,多行文本溢出省略(按行数)

○ 纯 CSS 实现方案

****核心 CSS 语句****

********优点********

**********短板**********

image

**********************适**********用场景************

**************Demo**************

<style>    .demo {          display: -webkit-box;        overflow: hidden;        -webkit-line-clamp: 2;        -webkit-box-orient: vertical;    }</style><body>    <div class='demo'>这是一段很长的文本</div></body>

****************示例图片****************

image.gif

○ 基于 JavaScript 的实现方案

********优点********

**********短板**********

**********************适**********用场景************

**************Demo**************

当前仅适用于文本为中文,若文本中有英文,可自行修改

<script type="text/javascript">    const text = '这是一段很长的文本';    const totalTextLen = text.length;    const formatStr = () => {        const ele = document.getElementsByClassName('demo')[0];        const lineNum = 2;        const baseWidth = window.getComputedStyle(ele).width;        const baseFontSize = window.getComputedStyle(ele).fontSize;        const lineWidth = +baseWidth.slice(0, -2);        // 所计算的strNum为元素内部一行可容纳的字数(不区分中英文)        const strNum = Math.floor(lineWidth / +baseFontSize.slice(0, -2));        let content = '';          // 多行可容纳总字数        const totalStrNum = Math.floor(strNum * lineNum);        const lastIndex = totalStrNum - totalTextLen;        if (totalTextLen > totalStrNum) {            content = text.slice(0, lastIndex - 3).concat('...');        } else {            content = text;        }        ele.innerHTML = content;    }    formatStr();        window.onresize = () => {        formatStr();    };</script><body>    <div class='demo'></div></body>

****************示例图片****************

image

再进阶一步,多行文本溢出省略(按高度)

○ 多行文本溢出不显示省略号

******核心 CSS 语句******

********优点********

**********短板**********

**********************适**********用场景************

****************Demo****************

<style>    .demo {        overflow: hidden;        max-height: 40px;        line-height: 20px;    }</style><body>    <div class='demo'>这是一段很长的文本</div></body>

******************示例图片******************

image

○ 伪元素 + 定位实现多行省略

******核心 CSS 语句******

********优点********

**********短板**********

************************适**********用场景**************

**************Demo**************

<style>    .demo {        position: relative;        line-height: 20px;        height: 40px;        overflow: hidden;    }    .demo::after {        content: "...";        position: absolute;        bottom: 0;        right: 0;        padding: 0 20px 0 10px;    }</style><body>    <div class='demo'>这是一段很长的文本</div></body>

****************示例图片****************

image

○ 利用 Float 特性,纯 CSS 实现多行省略

******核心 CSS 语句******

********优点********

**********短板**********

**********************适**********用场景************

**************Demo**************

<style>    .demo {        background: #099;        max-height: 40px;        line-height: 20px;        overflow: hidden;    }    .demo::before{        float: left;        content:'';        width: 20px;        height: 40px;    }    .demo .text {        float: right;        width: 100%;        margin-left: -20px;        word-break: break-all;    }    .demo::after{        float:right;        content:'...';        width: 20px;        height: 20px;        position: relative;        left:100%;        transform: translate(-100%,-100%);    }</style><body>    <div class='demo'>这是一段很长的文本</div></body>

****************示例图片****************

image.gif

******************原理讲解******************

有 A、B、C 三个盒子,A 左浮动,B、C 右浮动。设置 A 盒子的高度与 B 盒子高度(或最大高度)要保持一致

  1. 当 B 盒子高度低于 A 盒子,C 盒子仍会处于 B 盒子右下方。

  2. 如果 B 盒子文本过多,高度超过了 A 盒子,则 C 盒子不会停留在右下方,而是掉到了 A 盒子下。

  3. 接下来对 C 盒子进行相对定位,将 C 盒子位置向右侧移动 100%,并向左上方向拉回一个 C 盒子的宽高(不然会看不到哟)。这样在文本未溢出时不会看到 C 盒子,在文本溢出时,显示 C 盒子。

image

收,大道归简,能力封装

凡重复的,让它单一;凡复杂的,让它简单。

每次都要搞一坨代码,太麻烦。这时候你需要考虑将文本截断的能力,封装成一个可随时调用的自定义容器组件。市面上很多 UI 组件库,都提供了同类组件的封装,如基于 Vue 的 ViewUI Pro,或面向小程序提供组件化解决能力的 MinUI。

image image

结语

本文介绍了几种目前常见的文本截断省略的方案,各有利弊,各位同学可根据实际开发情况及需求选择方案。如果你还知道更好其他实现方案,欢迎在评论区留下宝贵评论。

参考文章

上一篇 下一篇

猜你喜欢

热点阅读