CSS 中实现单行、多行文字截断
Category(分类): CSS, HTML Status: 未知
在卡片标题、文章摘要、列表项和移动端信息流中,文字长度经常会超过容器的可用空间。常见的处理方式包括:
- 使用
text-overflow: ellipsis实现单行省略; - 使用
-webkit-line-clamp实现多行省略; - 使用伪元素覆盖文字,模拟多行省略号;
- 使用浮动和伪元素实现“内容溢出时才显示省略号”的传统方案;
- 对复杂内容使用 JavaScript 测量和截断。
现代项目应优先使用标准化程度较高、行为稳定的方案;传统方案可以用于维护旧项目或浏览器兼容场景。
1. 单行文本截断:text-overflow
单行文本截断最常用的写法是:
.single-line {
width: 240px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}

这几个属性需要配合使用:
white-space: nowrap:禁止文本换行;overflow: hidden:隐藏超出容器的内容;text-overflow: ellipsis:在被截断的位置显示省略号;width、max-width或其他布局约束:为文本提供有限的显示空间。
如果元素是普通行内元素,通常还需要将它设置为块级或行内块级:
.single-line {
display: block;
max-width: 100%;
}
text-overflow 本身不会主动设置宽度,也不会自动产生溢出。只有文本确实超出受限的内容区域时,省略号才会显示。
适用场景
- 单行标题;
- 用户名、标签、文件名;
- 导航菜单;
- 宽度受限的列表项。
注意事项
单行省略可能隐藏重要信息。对于需要完整阅读的内容,可以配合 title、展开按钮、详情页或可访问的完整文本使用:
<p class="single-line" title="这是一段完整的标题文本">
这是一段可能比较长的标题文本
</p>
2. 多行文本截断:-webkit-line-clamp
-webkit-line-clamp 是目前实际项目中使用广泛的多行文本截断方案。常见写法如下:
.multi-line {
display: -webkit-box;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}

它通常需要以下属性配合:
display: -webkit-box:使用旧版 WebKit 盒模型布局;-webkit-box-orient: vertical:让子内容沿垂直方向排列;-webkit-line-clamp: 2:最多显示两行;overflow: hidden:隐藏超出行数的内容。
text-overflow: ellipsis 可以作为补充,但在这种多行截断组合中通常不是决定性属性:
.multi-line {
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
}
兼容性说明
虽然属性名带有 -webkit- 前缀,但当前 Chromium、Safari 和 Firefox 均支持这种常见组合;IE 不支持。无前缀的 line-clamp 正在逐步得到支持,但仍应根据项目的目标浏览器进行测试。
因此,不应再简单描述为“只有 WebKit 内核浏览器支持”。如果需要兼容较旧浏览器,可以准备固定高度、伪元素或 JavaScript 回退方案。
通过行高限制高度的辅助写法
如果项目需要使用固定行高,也可以使用 max-height 限制显示高度:
.multi-line-fallback {
display: -webkit-box;
overflow: hidden;
max-height: 4.5em; /* 1.5 × 3 行 */
line-height: 1.5;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
}
不过,单独使用 max-height 只会裁剪内容,不一定会自动生成省略号。
适用场景
- 移动端信息流;
- 卡片摘要;
- 多行文章标题;
- 固定高度的内容列表。
3. 使用定位伪元素模拟多行省略号
在无法使用 -webkit-line-clamp 或需要兼容旧浏览器时,可以通过固定高度、overflow: hidden 和伪元素模拟省略号:
.excerpt {
position: relative;
height: 36px;
overflow: hidden;
line-height: 18px;
}
.excerpt::after {
position: absolute;
right: 0;
bottom: 0;
width: 3em;
padding-left: 2em;
color: currentColor;
background: linear-gradient(
to right,
rgb(255 255 255 / 0),
#fff 50%,
#fff
);
content: '...';
}

它的基本原理是:
- 通过固定
height和line-height控制最多显示的行数; - 通过
overflow: hidden隐藏超出部分; - 让绝对定位的
::after覆盖在最后一行右侧; - 使用渐变遮盖最后几个字符,并显示模拟省略号。
这种方案的优点
- 实现方式简单;
- 不依赖
-webkit-line-clamp; - 可以在旧浏览器中使用;
- 可以通过渐变调整省略号与文字的衔接效果。
这种方案的缺点
它无法可靠判断文本是否真的溢出,因此短文本也可能显示省略号。背景色写死为白色时,如果容器背景不是白色,遮罩也会出现明显问题。
此外,固定高度方案还需要考虑:
- 字体和行高变化;
padding、border和box-sizing;- 中英文混排的换行差异;
- 从左到右和从右到左的书写方向;
- 省略号遮挡最后几个字符的情况。
如果确实需要拆分较长英文单词,优先考虑:
.excerpt {
overflow-wrap: anywhere;
}
不要默认使用 word-break: break-all,因为它可能把英文单词任意拆开,影响可读性。
:after 与 ::after
原文中还单独列出了 :after 选择器。:after 是早期兼容写法,现代 CSS 推荐使用双冒号:
.excerpt::after {
content: '...';
}
两者在多数现代浏览器中的效果相同,但 ::after 更能明确表示这是伪元素,而不是伪类。


4. 使用浮动特性实现多行文本截断
如果要求“文本没有溢出时不显示省略号,文本溢出时才显示省略号”,单纯的定位伪元素方案很难准确判断文本长度。原文介绍了一种利用浮动布局特性的传统技巧。
这种方案的基本思路是:
- 设置一个固定高度的容器作为可视区域;
- 使用左浮动的伪元素占据固定高度和宽度;
- 让文本区域向右浮动并通过负外边距抵消占位;
- 让省略号伪元素浮动到文本区域附近;
- 当文本内容超过容器高度时,省略号浮动到可见区域;
- 当文本没有溢出时,省略号被推到容器外,再由
overflow: hidden隐藏。


可以把三个区域理解为:
- 粉色区域:占据固定高度的左浮动占位元素;
- 浅蓝色区域:实际文本区域;
- 黄色区域:模拟省略号的元素。
当浅蓝色文本区域的高度没有超过粉色占位区域时,黄色区域会处于容器外侧;当文本内容过多、文本区域高度超过粉色区域时,黄色区域会移动到文本的右下方。

简化后的 HTML
<div class="wrap">
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Dignissimos labore sit vel itaque delectus atque quos magnam
assumenda quod architecto perspiciatis animi.
</div>
</div>
浮动截断代码
.wrap {
height: 40px;
overflow: hidden;
line-height: 20px;
}
.wrap .text {
float: right;
width: 100%;
margin-left: -5px;
overflow-wrap: anywhere;
}
.wrap::before {
float: left;
width: 5px;
height: 40px;
content: '';
}
.wrap::after {
position: relative;
top: -20px;
left: 100%;
float: right;
width: 3em;
height: 20px;
margin-left: -3em;
padding-right: 5px;
line-height: 20px;
content: '...';
}

这种方案的优点
- 不依赖
-webkit-line-clamp; - 在合适的固定行高场景下,可以根据溢出状态决定是否显示模拟省略号;
- 可以根据容器宽度响应式换行。
这种方案的缺点
浮动技巧依赖复杂的布局细节,维护成本较高,可能受到以下因素影响:
- 字体、行高和容器高度改变;
- 文本中包含链接、图片或其他行内元素;
- 中英文混排和单词换行;
- RTL 文字方向;
- 省略号与最后一行文字的位置;
- 不同浏览器的浮动和行盒实现差异。
因此,现代项目通常优先使用 -webkit-line-clamp。只有在需要兼容旧环境,或者确实需要研究传统 CSS 布局技巧时,才考虑使用这种方案。
5. CSS 截断方案对比
| 方案 | 适用场景 | 优点 | 局限 |
|---|---|---|---|
text-overflow: ellipsis | 单行文本 | 简单、稳定、易维护 | 主要用于单行 |
-webkit-line-clamp | 多行文本 | 代码少、效果自然 | 需要结合旧版 WebKit 盒模型写法,旧浏览器不支持 |
| 定位伪元素 | 旧浏览器、固定内容区域 | 实现直观 | 无法准确判断是否溢出,短文本可能也显示省略号 |
| 浮动伪元素 | 传统兼容方案 | 特定条件下可根据溢出状态显示省略号 | 依赖布局技巧,容易受到内容和浏览器差异影响 |
| JavaScript 测量 | 复杂内容、严格控制 | 可精确检测和处理 | 需要处理字体加载、窗口变化和性能问题 |
6. 需要精确截断时使用 JavaScript
如果内容包含复杂内联元素,或者必须确保省略号只在实际溢出时出现,可以使用 JavaScript 测量元素的滚动尺寸:
const element = document.querySelector('.excerpt')
if (element) {
const isOverflowing = element.scrollHeight > element.clientHeight
element.classList.toggle('is-overflowing', isOverflowing)
}
如果需要按字符截断,应特别注意:
- 中英文混排;
- Emoji 由多个 Unicode 代码点组成;
- 部分文字由组合字符组成;
- 不要简单使用
textContent.slice()就认为每个字符都能安全拆分; - 窗口尺寸、字体加载和容器宽度变化时需要重新计算。
更复杂的场景可以使用 Intl.Segmenter 进行用户感知字符分段,但仍需要根据浏览器目标和内容结构进行测试。
7. 可访问性注意事项
视觉上的省略号不应成为用户获取信息的唯一方式。对于重要标题和摘要,建议:
- 保留 DOM 中的完整文本;
- 提供详情页或“展开全文”按钮;
- 使用
title作为简单补充,但不要把它当作唯一的无障碍方案; - 不要仅依赖 CSS
content: '...'传递关键信息; - 截断按钮需要有明确的可访问名称和键盘操作支持。
总结
- 单行文本优先使用
white-space、overflow和text-overflow; - 多行文本优先使用
-webkit-line-clamp组合; -webkit-line-clamp已被现代主流浏览器广泛支持,但 IE 不支持;- CSS 注释必须使用
/* ... */,不能使用 JavaScript 风格的//; - 定位伪元素方案简单,但无法可靠判断文本是否溢出;
- 浮动方案能够体现传统 CSS 布局技巧,但对高度、行高和内容结构比较敏感;
- 不要默认使用
word-break: break-all,优先考虑overflow-wrap: anywhere; - 对复杂文本或严格截断需求,可以使用 JavaScript 测量;
- 截断内容时应保留完整信息,兼顾可访问性和键盘操作。