logoAnt Design

⌘ K
  • 디자인
  • 개발
  • 컴포넌트
  • 블로그
  • 자료
5.21.3
  • 为什么禁用日期这么难?
  • Why is it so hard to disable the date?
  • 封装 Form.Item 实现数组转对象
  • HOC Aggregate FieldItem
  • 行省略计算
  • Line Ellipsis Calculation
  • 📢 v4 维护周期截止
  • 📢 v4 surpassed maintenance period
  • Type Util
  • 一个构建的幽灵
  • A build ghost
  • 当 Ant Design 遇上 CSS 变量
  • Ant Design meets CSS Variables
  • API 기술 부채
  • 생동감 있는 Notification
  • 色彩模型与颜色选择器
  • Color Models and Color Picker
  • 主题拓展
  • Extends Theme
  • 虚拟表格来了!
  • Virtual Table is here!
  • Happy Work 테마
  • Happy Work Theme
  • 동적 스타일은 어디로 갔을까?
  • Suspense 引发的样式丢失问题
  • Suspense breaks styles
  • Bundle Size Optimization
  • 안녕, GitHub Actions
  • 所见即所得
  • To be what you see
  • 정적 메서드의 고통
  • SSR에서 정적 스타일 추출
  • SSR Static style export
  • 의존성 문제 해결
  • 贡献者开发维护指南
  • Contributor development maintenance guide
  • 转载-如何提交无法解答的问题
  • Repost: How to submit a riddle
  • 新的 Tooltip 对齐方式
  • Tooltip align update
  • Unnecessary Rerender
  • 如何成长为 Collaborator
  • How to Grow as a Collaborator
  • Funny Modal hook BUG
  • Modal hook 的有趣 BUG
  • about antd test library migration
  • antd 测试库迁移的那些事儿
  • Tree 的勾选传导
  • Tree's check conduction
  • getContainer 的一些变化
  • Some change on getContainer
  • Component-level CSS-in-JS

行省略计算

Resources

Ant Design Charts
Ant Design Pro
Ant Design Pro Components
Ant Design Mobile
Ant Design Mini
Ant Design Landing-Landing Templates
Scaffolds-Scaffold Market
Umi-React Application Framework
dumi-Component doc generator
qiankun-Micro-Frontends Framework
ahooks-React Hooks Library
Ant Motion-Motion Solution
China Mirror 🇨🇳

Community

Awesome Ant Design
Medium
Twitter
yuque logoAnt Design in YuQue
Ant Design in Zhihu
Experience Cloud Blog
seeconf logoSEE Conf-Experience Tech Conference
Work with Us

Help

GitHub
Change Log
FAQ
Bug Report
Issues
Discussions
StackOverflow
SegmentFault

Ant XTech logoMore Products

yuque logoYuQue-Document Collaboration Platform
AntV logoAntV-Data Visualization
Egg logoEgg-Enterprise Node.js Framework
Kitchen logoKitchen-Sketch Toolkit
Galacean logoGalacean-Interactive Graphics Solution
xtech logoAnt Financial Experience Tech
Theme Editor
Made with ❤ by
Ant Group and Ant Design Community
loading

Ant Design 的 Typography 组件提供了一个 ellipsis 属性,用于在文本溢出时显示省略号。它支持通过配置 ellipsis.rows 来限定显示的行数。如果是纯粹的文本内容,它会通过 CSS -webkit-line-clamp 属性来实现。虽然有 -webkit- 前缀,但是在现代浏览器中都已经得到了很好的支持。

<div
style={{
display: '-webkit-box',
overflow: 'hidden',
WebkitBoxOrient: 'vertical',
webkitLineClamp: 3,
}}
>
{text}
</div>

row ellipsis

CSS 的一些问题

然而 CSS 实现也有限制,那就是不支持对省略符号的修改以及对附加操作按钮的支持(比如置于最后的 复制、编辑、展开 等按钮)。

with action

操作按钮会被一同截断,无法显示。

ellipsis with action

虽然有一些黑魔法手段可以通过诸如 float 样式来实现,但是这样的方式在不同的浏览器中需要做针对性处理。此外仍然无法解决自定义省略符号的问题。因而目前最好的实现方式仍然是通过 JS 来实现。

JS 实现

JS 中,我们通过二分法可以快速的找到文本的截断位置。只要根据 rows 推断出文本的高度,然后进行遍历,找到最大可以展示的文字数量即可:

Cell Cut

而行高则可以通过模拟埋入一个 span 来获取:

<div>
{text}
{measuring && <span ref={measureRef}>&nbsp;</span>}
</div>

Measure

但是这样的方式也有一些问题,对于混合行高的场景(比如添加了图片、嵌入不同大小的文字等等)。这种计算方式往往会估算出错误的总高度,而使得裁剪位置不准确:

Mixed Line Height

由于图片高度超出了行高,导致计算认为这个图片占用了两行的高度。同时又因为图片本身无法裁剪,使得最终省略行数错误(3 行省略变成了 2 行):

Mixed Line Height Ellipsis

如果图片在第一行,那整个文本就会被截断:

Image on the first line

而如果使用 CSS 则不会有这个问题:

CSS Ellipsis

混合测量

为了解决这个问题,我们可以通过混合测量的方式来解决。即通过 CSS 来测量原生多行省略的总高度,然后再通过 JS 进行二分法来确定文本的截断位置最终不要超过 CSS 测量的总高度:

<div ref={measureRef} style={ellipsisStyle}>
{text}
</div>;
const cssHeight = measureRef.current.clientHeight;
// pseudocode. Not used in real world
<div ref={walkingMeasureRef}>{text.slice(0, walkingMeasureIndex)}</div>;
if (walkingMeasureRef.current.clientHeight > cssHeight) {
// Not meet the requirement
}

这样就可以准确的处理混合行高的场景:

Mixed Line Height Ellipsis

总结

通过混合测量的方式,我们可以非常容易的利用 CSS 的准确性和 JS 的灵活性,实现即使在包含图片等不同行高元素的复杂内容中,也能实现准确的文本截断。

该重构已经在 5.15.0 中发布,欢迎体验。