写点什么

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

  • 2021-02-22
  • 本文字数:3557 字

    阅读完需:约 12 分钟

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

前言


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


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


核心 CSS 语句 

  • overflow: hidden;(文字长度超出限定宽度,则隐藏超出的内容)

  • white-space: nowrap;(设置文字在一行显示,不能换行)

  • text-overflow: ellipsis;(规定当文本溢出时,显示省略符号来代表被修剪的文本)

优点

  • 无兼容问题

  • 响应式截断

  • 文本溢出范围才显示省略号,否则不显示省略号

  • 省略号位置显示刚好

短板

  • 只支持单行文本截断

适用场景

  • 适用于单行文本溢出显示省略号的情况

Demo

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

示例图片


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

纯 CSS 实现方案核心


核心 CSS 语句

  • -webkit-line-clamp: 2;(用来限制在一个块元素显示的文本的行数,2 表示最多显示 2 行。为了实现该效果,它需要组合其他的 WebKit 属性)

  • display: -webkit-box;(和 1 结合使用,将对象作为弹性伸缩盒子模型显示 )

  • -webkit-box-orient: vertical;(和 1 结合使用 ,设置或检索伸缩盒对象的子元素的排列方式 )

  • overflow: hidden;(文本溢出限定的宽度就隐藏内容)

  • text-overflow: ellipsis;(多行文本的情况下,用省略号 “…” 隐藏溢出范围的文本)

优点

  • 响应式截断

  • 文本溢出范围才显示省略号,否则不显示省略号

  • 省略号显示位置刚好

短板

  • 兼容性一般:-webkit-line-clamp 属性只有 WebKit 内核的浏览器才支持


用场景

  • 多适用于移动端页面,因为移动设备浏览器更多是基于 WebKit 内核

Demo

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

示例图片


基于 JavaScript 的实现方案优点


优点

  • 无兼容问题

  • 响应式截断

  • 文本溢出范围才显示省略号,否则不显示省略号

短板

  • 需要 JS 实现,背离展示和行为相分离原则

  • 文本为中英文混合时,省略号显示位置略有偏差

适用场景

适用于响应式截断,多行文本溢出省略的情况

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>
复制代码


示例图片



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


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


核心 CSS 语句

  • overflow: hidden;(文本溢出限定的宽度就隐藏内容)

  • line-height: 20px;(结合元素高度,高度固定的情况下,设定行高, 控制显示行数)

  • max-height: 40px;(设定当前元素最大高度)

优点

  • 无兼容问题

  • 响应式截断

短板

  • 单纯截断文字, 不展示省略号,观感上较为生硬

用场景

  • 适用于文本溢出不需要显示省略号的情况

Demo

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

示例图片


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


核心 CSS 语句

  • position: relative; (为伪元素绝对定位)

  • overflow: hidden; (文本溢出限定的宽度就隐藏内容)

  • position: absolute;(给省略号绝对定位)

  • line-height: 20px; (结合元素高度,高度固定的情况下,设定行高, 控制显示行数)

  • height: 40px; (设定当前元素高度)

  • ::after {}  (设置省略号样式)

优点

  • 无兼容问题

  • 响应式截断

短板

  • 无法识别文字的长短,无论文本是否溢出范围, 一直显示省略号

  • 省略号显示可能不会刚刚好,有时会遮住一半文字

用场景

  • 适用于对省略效果要求较低,文本一定会溢出元素的情况

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>
复制代码

示例图片


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


核心 CSS 语句

  • line-height: 20px;(结合元素高度,高度固定的情况下,设定行高, 控制显示行数)

  • overflow: hidden;(文本溢出限定的宽度就隐藏内容)

  • float: right/left;(利用元素浮动的特性实现)

  • position: relative;(根据自身位置移动省略号位置, 实现文本溢出显示省略号效果)

  • word-break: break-all;(使一个单词能够在换行时进行拆分)

优点

  • 无兼容问题

  • 响应式截断

  • 文本溢出范围才显示省略号,否则不显示省略号

短板

  • 省略号显示可能不会刚刚好,有时会遮住一半文字

用场景

  • 适用于对省略效果要求较低,多行文本响应式截断的情况

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>
复制代码

示例图片

原理讲解


有 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 盒子。



收,大道归简,能力封装


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


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




结语


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



头图:Unsplash

作者:亚格

原文:https://mp.weixin.qq.com/s/HhSdZ1RBSRZt9I84qZj6oA

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

来源:政采云前端团队 - 微信公众号 [ID:Zoo-Team]

转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2021-02-22 09:005003

评论

发布
暂无评论
发现更多内容

Redis复制的实现

急需上岸的小谢

9月月更

论监控中事件管理的艺术

穿过生命散发芬芳

事件管理 9月月更

等保2.0是什么意思?谁能详细解释一下!

行云管家

云计算 等保 等级保护 等保2.0

一招教你如何高效批量导入与更新数据

华为云开发者联盟

数据库 sql 后端 企业号九月金秋榜

PSYNC 命令的实现

急需上岸的小谢

9月月更

荣耀帐号服务,让用户获取变得更简单

荣耀开发者服务平台

手机 物联网 安卓 移动开发 honor

依据TIdb执行计划的sql调优案例分享

TiDB 社区干货传送门

性能调优 管理与运维 HTAP 场景实践 大数据场景实践

理解elasticsearch的post_filter

程序员欣宸

elasticsearch 9月月更

FreeRTOS记录(十、FreeRTOS实现带 I2C 通讯的 ModbusRTU 协议从机实例)

矜辰所致

FreeRTOS 9月月更 ModbusRTU

PhotoView——支持图片缩放、平移、旋转的一个优雅的三方组件

OpenHarmony开发者

Open Harmony

活动报名| MongoDB 核心功能及其原理分析

MongoDB中文社区

mongodb

奇点云数据云平台发布DataSimba R3.8长期支持版

奇点云

奇点云

TiDB生命周期

TiDB 社区干货传送门

实践案例 集群管理 管理与运维 数据库架构设计

跨链自动化中心 OAK Network,构建安全高效 Web3 基础设施

One Block Community

Substrate defi 跨链 区块链、

MyBatis-Plus(二、常用注解)

注解 MyBatisPlus 9月月更

压测平台在全链路大促压测中的实践

得物技术

中间件 全链路压测 QPS 企业号九月金秋榜

一步步搞懂MySQL元数据锁(MDL)

京东科技开发者

MySQL 数据库 元数据 数据库锁 mdl

【微信小程序】常用组件及基本使用详解

陈橘又青

小程序开发 9月月更

2022-09微软漏洞通告

火绒安全

microsoft 安全 终端安全 安全漏洞

十年大厂资深面试官告诉你,现在Java面试八股文都已经卷到什么程度了

Java永远的神

程序员 程序人生 设计模式 中间件 java面试

StarlingX 7.0 已发布!进一步强化可扩展性、安全性及灵活性

极客天地

mysql 查询执行过程

急需上岸的小谢

9月月更

VUE3中watch与watchEffect —— 全网最详细系列

海底烧烤店ai

前端 响应式编程 Vue3 9月月更

云安全是什么?是哪个企业提出的概念?

行云管家

云计算 网络安全 安全 云安全

Vite构建的Vue3项目打包部署到Gitee —— 全网最详细系列

海底烧烤店ai

前端 vite Vue3 部署 9月月更

TiDB分布式事务—写写冲突

TiDB 社区干货传送门

故障排查/诊断

Vite+Vue3+Vue-Router+Vuex+CSS预处理器(less/sass) 配置指南 —— 全网最详细系列

海底烧烤店ai

前端 Vue3 9月月更 项目搭建

力扣151 - 反转字符串中的单词【双指针与字符串的火花】

Fire_Shield

双指针 LeetCode 9月月更

TiDB部署----openEuler2203/2003 单机部署TiDB 6.1.1

TiDB 社区干货传送门

安装 & 部署

送你5个MindSpore算子使用经验

华为云开发者联盟

人工智能 算子 企业号九月金秋榜

可能是最全的 “文本溢出截断省略” 方案合集_编程语言_政采云前端团队_InfoQ精选文章