logoAnt Design

⌘ K
  • 设计
  • 研发
  • 组件
  • 博客
  • 资源
  • 国内镜像
5.25.4
  • v6 的一些 CSS 琐事
  • 👀 视觉回归测试
  • 为什么禁用日期这么难?
  • 封装 Form.Item 实现数组转对象
  • 行省略计算
  • 📢 v4 维护周期截止
  • antd 里常用的 TypeScript 工具方法
  • 一个构建的幽灵
  • 当 Ant Design 遇上 CSS 变量
  • API 的历史债务
  • 灵动的 Notification
  • 色彩模型与颜色选择器
  • 主题拓展
  • 虚拟表格来了!
  • 快乐工作主题(一)
  • 动态样式去哪儿了?
  • Suspense 引发的样式丢失问题
  • 打包体积优化
  • 你好,GitHub Actions
  • 所见即所得
  • 静态方法之痛
  • SSR 静态样式导出
  • 依赖排查
  • 贡献者开发维护指南
  • 转载-如何提交无法解答的问题
  • 新的 Tooltip 对齐方式
  • 非必要的渲染
  • 如何成长为 Collaborator
  • Modal hook 的有趣 BUG
  • antd 测试库迁移的那些事儿
  • Tree 的勾选传导
  • getContainer 的一些变化
  • 组件级别的 CSS-in-JS
CSS 的一些问题
JS 实现
混合测量
总结

行省略计算

2024-03-01
@zombieJ
文档贡献者
  • 封装 Form.Item 实现数组转对象📢 v4 维护周期截止

    相关资源

    Ant Design X
    Ant Design Charts
    Ant Design Pro
    Pro Components
    Ant Design Mobile
    Ant Design Mini
    Ant Design Web3
    Ant Design Landing-首页模板集
    Scaffolds-脚手架市场
    Umi-React 应用开发框架
    dumi-组件/文档研发工具
    qiankun-微前端框架
    Ant Motion-设计动效
    国内镜像站点 🇨🇳

    社区

    Awesome Ant Design
    Medium
    Twitter
    yuque logoAnt Design 语雀专栏
    Ant Design 知乎专栏
    体验科技专栏
    seeconf logoSEE Conf-蚂蚁体验科技大会
    加入我们

    帮助

    GitHub
    更新日志
    常见问题
    报告 Bug
    议题
    讨论区
    StackOverflow
    SegmentFault

    Ant XTech logo更多产品

    yuque logo语雀-构建你的数字花园
    AntV logoAntV-数据可视化解决方案
    Egg logoEgg-企业级 Node.js 框架
    Kitchen logoKitchen-Sketch 工具集
    Galacean logoGalacean-互动图形解决方案
    xtech logo蚂蚁体验科技
    主题编辑器
    Made with ❤ by
    蚂蚁集团和 Ant Design 开源社区

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

    tsx
    <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 来获取:

    tsx
    <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 测量的总高度:

    tsx
    <div ref={measureRef} style={ellipsisStyle}>
    {text}
    </div>;
    const cssHeight = measureRef.current.clientHeight;
    tsx
    // 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 中发布,欢迎体验。