12k
All articles

如何在 CSS 中截断文本

用CSS截断文本:单行用text-overflow: ellipsis,多行用line-clamp,并包含flex和grid中的常见修复。

OpenReplay Team
OpenReplay Team
如何在 CSS 中截断文本

在 CSS 中截断文本,可使用 text-overflow: ellipsis 裁剪单行文本,使用 line-clamp 将文本限制在固定行数内——这一区别决定了所有其他的处理方式。

如果你曾经看到卡片标题直接溢出容器,而 text-overflow: ellipsis 毫无作用,你一定深有体会。失败的原因几乎总是以下两种之一:针对所需行数选用了错误的技术,或者 flex 父容器悄悄拒绝收缩。单行截断需要三个声明协同工作;多行截断需要 -webkit-box 三件套。在生产环境中真正容易出问题的地方其实很有限:ellipsis 在 flexbox 内部会静默失效,多行截断在文本无法换行时会失效,而基于 JavaScript 的截断会悄悄破坏屏幕阅读器所需的内容。本文将逐一介绍每种可行方案及其对应的注意事项。

以下是决策规则的表格形式:

目标技术必需声明省略号可自定义?
裁剪至单行text-overflow: ellipsiswhite-space: nowrap; overflow: hidden; text-overflow: ellipsis可通过 <string> 值自定义
裁剪至 N 行line-clampdisplay: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: N; overflow: hidden不可自定义

核心要点

  • 单行截断需要三个声明协同工作:white-space: nowrap 阻止文本换行,overflow: hidden 裁剪溢出内容,text-overflow: ellipsis 添加 。元素还需要一个约束宽度,否则不存在溢出的条件。
  • 多行截断需设置 display: -webkit-box-webkit-box-orient: vertical-webkit-line-clamp: N 以及 overflow: hidden;这组带前缀的属性在所有主流浏览器中均受支持。
  • 标准化的无前缀 line-clamp 已在 CSS Overflow Module Level 4 中定义,但截至 2026 年尚未成为 Baseline,因此应将其与 -webkit- 声明并列添加,而非替换后者。
  • Ellipsis 在 flex 或 grid 子元素上会静默失效,因为其默认的 min-width: auto 拒绝收缩至内容宽度以下;在该子元素上设置 min-width: 0 即可解决此问题。
  • CSS 截断属于表现层处理,完整字符串仍保留在 DOM 中,屏幕阅读器可完整读取,这与 JavaScript 的 substring 截断不同——后者会直接删除文本。

如何截断单行文本?

要截断单行文本,需要三个声明协同工作:white-space: nowrap 阻止文本换行,overflow: hidden 裁剪溢出内容,text-overflow: ellipsis 添加 。缺少其中任何一个,效果都会失效:单独使用 text-overflow 对已换行的文本毫无作用,而没有 overflow: hidden 则不存在供省略号依附的裁剪框。

.truncate {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

元素还需要一个约束宽度。如果容器足够宽,能将整个字符串显示在一行内,则不会发生溢出,也不会出现省略号:父元素的宽度才是触发截断的关键。可将此样式应用于卡片、表格单元格、导航项或必须保持单行的标题。

text-overflow 属性接受 clip(默认的硬截断)、ellipsis 以及自定义 <string> 值。此外还有 fade 关键字和 fade() 函数,已被加入 CSS Overflow Level 4 标准并在 MDN 的正式语法中有所记录,但实际上没有任何浏览器实现了它们,因此不要在生产环境中依赖这两者。

如何将文本截断至多行?

多行截断需设置 display: -webkit-box-webkit-box-orient: vertical-webkit-line-clamp: N 以及 overflow: hidden。尽管带有厂商前缀,这一组合在所有主流浏览器中均受支持,是目前生产环境中的可靠方案。

.clamp {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}

务必保留 overflow: hidden。正如 MDN 所指出的,若不设置此属性,文本实际上不会被裁剪,但省略号仍会出现在指定行数之后,导致省略号和溢出文本同时可见。这些带前缀的属性之间也存在相互依赖关系:-webkit-line-clamp 只有在 display-webkit-box(或 -webkit-inline-box)且 -webkit-box-orientvertical 时才会生效。这些带前缀的属性已被正式标记为废弃,但这种三方依赖关系本身是已规范化的行为,浏览器将持续支持,因此在生产环境中使用并无实际风险。

有一个需要注意的失效场景:多行截断仅在文本允许换行时才有效。继承的 white-space: nowrap 会悄悄破坏它,将所有内容折叠到一行。请将 white-space 保持为 normalpre-wrap

此外,CSS Overflow Module Level 4 中定义了无前缀的标准 line-clamp 属性,用于将块级内容限制在指定行数内。然而截至 2026 年,该属性仍被标记为非 Baseline 状态,因为部分广泛使用的浏览器尚不支持。建议将其视为渐进增强特性,与带前缀的声明并列添加,而非替换后者:

.clamp {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3; /* 标准化属性,并列添加——目前尚不能替代带前缀版本 */
  overflow: hidden;
}

为什么 ellipsis 在 flexbox(及 grid)内部失效

Ellipsis 在 flex 子元素上会静默失效,原因在于 flex 子项的默认 min-width: auto 拒绝收缩至内容宽度以下,导致元素始终无法变得足够窄以产生溢出,text-overflow 也就没有可裁剪的内容。子元素会直接突破容器,而不是触发截断。解决方法是在子元素上添加一个声明:

.card { display: flex; }

.card__label {
  min-width: 0; /* 覆盖自动最小值,使子项可以收缩 */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

min-width: auto 自动最小尺寸同样适用于 grid 子项,因此在 CSS Grid 轨道内的截断也会因同样的原因失效。解决方法相同:在子元素上设置 min-width: 0(或设置 overflow: hidden,同样可以解除自动最小值限制)。这是现实生产中最常见的截断 bug:CSS 单独看起来完全正确,只有当元素成为 flex 或 grid 子项时才会出现问题。

Tailwind 等效写法

Tailwind 内置了这两种模式的工具类,无需安装插件。truncate 工具类是一个复合类,同时设置 overflow: hiddentext-overflow: ellipsiswhite-space: nowrap,一个类名即可实现完整的单行截断方案。多行截断则使用 line-clamp-<n>(例如 line-clamp-3,或使用 line-clamp-none 禁用),会输出 -webkit-box 三件套。Line-clamp 工具类自 v3.3 起已成为 Tailwind 核心的一部分;当前稳定版本为 v4.3.3(2026 年 7 月),无需额外安装。

<p class="truncate">单行文本,以省略号截断…</p>
<p class="line-clamp-3">多行文本,限制为三行…</p>

在 flex 或 grid 子元素内部,添加 min-w-0:这是 min-width: 0 修复方案的工具类等效写法。

无障碍访问:CSS 截断 vs. JS 截断

由于 CSS 截断纯属表现层处理,完整字符串仍保留在 DOM 中,屏幕阅读器可完整读取,无需添加 aria-label。这是与 JavaScript 截断的决定性区别:使用 text.substring(0, 50) 的方式会重写 DOM 节点,被截断的文本对所有人都不可见,包括辅助技术用户,除非通过 titlearia-label 属性单独保留。

即便使用 CSS,截断仍会在视觉上隐藏信息。对生产界面的会话回放经常暴露此类问题:用户悬停或费力辨认被截断的表格单元格或导航项,而那里恰好隐藏着他们所需的关键信息。对于承载重要信息的内容,请配合使用 title 属性或展开交互控件:

<span class="truncate" title="Quarterly revenue report — EMEA region, Q3 2026">
  Quarterly revenue report — EMEA region, Q3 2026
</span>

有一个局限性需要了解:-webkit-line-clamp 的省略号无法自定义,且 text-overflow 对其不适用,因为 text-overflow 仅影响行内溢出。如果你需要在多行文本上使用自定义截断指示符,这意味着应该采用其他方案,而不是强行与 clamp 对抗。

需要单行时使用 text-overflow: ellipsis,需要多行时使用 line-clamp 三件套,一旦元素位于 flex 或 grid 内部就记得添加 min-width: 0,并在隐藏内容具有实际意义时添加 title 属性。掌握这些,就能覆盖那些能正常工作的模式,以及三种会悄悄失效的场景。

常见问题

text-overflow: ellipsis 和 line-clamp 有什么区别?

使用 text-overflow: ellipsis 裁剪单行文本,使用 line-clamp 将文本限制在固定行数内。单行截断需要三个声明协同工作:white-space: nowrap、overflow: hidden 和 text-overflow: ellipsis。多行截断需要 -webkit-box 三件套加上 overflow: hidden,且完全不响应 text-overflow,因为该属性仅影响行内溢出。

为什么我的 ellipsis 截断在 flexbox 或 grid 内部不起作用?

flex 或 grid 子项的默认 min-width: auto 拒绝收缩至内容宽度以下,导致元素始终无法变得足够窄以产生溢出,text-overflow 也就没有可裁剪的内容。在该子元素上设置 min-width: 0 可覆盖自动最小值,恢复截断效果。对子元素应用 overflow: hidden 同样可以解除自动最小值限制。这是最常见的现实截断 bug,因为 CSS 单独看起来完全正确,只有当元素成为 flex 或 grid 子项时才会出现问题。

2026 年可以单独使用无前缀的 line-clamp 属性吗?

不可以。标准化的无前缀 line-clamp 已在 CSS Overflow Module Level 4 中定义,但截至 2026 年,MDN 将其标记为非 Baseline 状态,因为部分广泛使用的浏览器尚不支持。应将其作为渐进增强特性,与 -webkit-box、-webkit-box-orient 和 -webkit-line-clamp 声明并列添加,而非替换后者。带前缀的三件套目前仍是生产环境中的可靠方案。

CSS 截断会影响屏幕阅读器的无障碍访问吗?

不会。CSS 截断纯属表现层处理,完整字符串仍保留在 DOM 中,屏幕阅读器可完整读取,无需添加 aria-label。问题在于 JavaScript 截断:substring 方式会重写 DOM 节点,对所有人(包括辅助技术用户)删除被截断的文本,除非通过 title 或 aria-label 单独保留。对于承载重要信息的内容,无论如何都应配合 CSS 截断使用 title 属性或展开交互控件。

Digital experience platform

Truly understand users experience

See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.