likes
comments
collection
share

Typography与Description的化学反应

作者站长头像
站长
· 阅读数 24

前情提要

在公司的日常需求开发中,遇到了一个问题,借此文章分享一下(文章中的配图都是通过demo复现的,不方便直接截图公司的网页)~

  • Description组件中使用Typography.Text组件,开启ellipsis
  • Description组件中使用Typography.Paragraph组件,也开启ellipsis

我们期望的结果

Typography与Description的化学反应

页面实际的结果

Typography与Description的化学反应

我的反应

Typography与Description的化学反应

为什么在别的页面的详情页,同样的组合方式就不会有这个问题?

Typography与Description的化学反应

Ant Design 的反应

Typography与Description的化学反应

直入主题

组件结构

Typography与Description的化学反应

控制变量法

1.Descriptions.Item中包裹的内容不同

是否是Typography.TextTypography.Paragraph对于溢出省略处理的方式不同,导致的最后展示结果不同?

Typography.Text的处理方式

代码展示

Typography与Description的化学反应

.ant-typography-single-line {
  white-space: nowrap;
}

.ant-typography-ellipsis-single-line {
    overflow: hidden;
    text-overflow: ellipsis;
}
  • text-overflow: 用于确定如何提示用户存在隐藏溢出内容。它有3个取值,分别是clip(默认值)、ellipsis、string(自定义字符串)。ellipsis指用省略号表示被裁减的文本。详细内容
  • overflow: 这里只提到一点,设置hidden时,会将溢出内容隐藏。详细内容
  • white-space: 这里只提到一点,设置nowrap时,使文本在一行内显示,防止文本自动换行。详细内容

思考❓:为什么 text-overflow一定要和white-spaceoverflow配套使用?

text-overflow 属性并不会强制“溢出”事件的发生,因此为了能让文本能够溢出容器,你需要在元素上添加几个额外的属性:overflowwhite-space。 —— MDN

Why white-space:nowrap

当文本超过指定容器宽度时,如果没有 white-space: nowrap; 属性,文本会自动换行,此时也就不会溢出当前容器了。

Typography与Description的化学反应

所以,white-space: nowrap; 属性的作用就是为了限制文本在一行内显示,这样当文本超过指定容器宽度时,不会自动换行而是溢出容器。

Typography与Description的化学反应

Why overflow:hidden

white-space: nowrap帮助我们创造了文本溢出容器的条件,而设置overflow:hidden则是帮助我们设置了元素溢出时所需的行为,即隐藏 溢出的内容

Typography与Description的化学反应

至此,text-overflow的作用说明中(“用于确定如何提示用户存在隐藏溢出内容”)提到的两个前置条件均被满足,于是它能够生效了。

Typography.Paragraph的处理方式

代码展示

Typography与Description的化学反应

.ant-typography-ellipsis-multiple-line {
  display: -webkit-box;
  overflow: hidden;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
}
  • -webkit-line-clamp: 可以把块容器中的内容限制为指定的行数,设置为整数值,如3,则内容展示为3行。详细内容
  • -webkit-box-orient: 用来设置一个元素是水平还是垂直布局其内容。详细内容

💡使用-webkit-line-clamp需要注意的地方

  • 它只有在 display 属性设置成 -webkit-box 或者 -webkit-inline-box 并且 box-orient 属性设置成 vertical时才有效果。
  • 在大部分情况下,也需要设置 overflow 属性为 hidden,否则,里面的内容不会被裁减,并且在内容显示为指定行数后还会显示省略号。

—— MDN

❗️需要注意的是,这种方法只适用于WebKit内核的浏览器,如Chrome、Safari等,其他浏览器可能不支持。此外,由于这种方式是非标准的私有属性,还有可能被未来的浏览器或版本所废弃。

思考分析

Typography与Description的化学反应

  • content给自己设置了flex:1的css属性,其中没有设置flex-basisflex:1 等价于flex: 1 1 0%,因此flex-basis的默认值是0%。
  • content并没有设置width ,在flex布局下,如果content包裹的子元素的宽度不超过content的父元素宽度,则content的宽度始终与父元素的宽度保持一致。反之,content的宽度会与它包裹的子元素保持一致。
  • flex布局实战链接

多行文本省略为什么有效

根据MDN的文档, -webkit-line-clamp生效的条件有3条

  • display 属性设置成 -webkit-box 或者 -webkit-inline-box
  • box-orient 属性设置成 vertical
  • 设置 overflow 属性为 hidden

这3个必要条件Typography.Paragraph都提供了,因此-webkit-line-clamp会生效。

单行文本溢出省略为什么无效?

回顾一下单行溢出省略生效的条件:1.溢出。2.省略。

由于content会随着单行文本内容宽度的增加,也增加自身的宽度,导致我们在Typography.Text中设置的overflow:hidden就无效了(无法超出容器,也就没有溢出的内容,巧妇难为无米之炊),自然而然,text-overflow:ellipsis也就无效了。

解决方案

那么我们的主要矛盾就从如何让text-overflow:ellipsis生效,变成了如何让overflow:hidden生效了。

overflow是对超出容器的内容进行处理的属性,而现在content的width 和 子元素单行文本的width是保持一致的,因此没有超出容器的内容可以hidden。

于是最简单的想法就是,给content设置一个具体明确的width,给单行文本的内容超出容器创造条件。

方案一

因此我们只要给content设置一个具体明确的width属性,即可解决这个问题。

当我们将固定宽度(假设width:1)给予content之后,content的宽度(1)没有超过父元素的宽度,又因为content设置了flex-grow:1且content是父元素唯一的直接子元素,因此content扩展,直至占满父元素。

此时content最终的宽度就是父元素的宽度。于是它所包裹的单行文本内容的overflow也就能够生效了。

而Antd刚好为Descriptins.Item开放了这个API。

Typography与Description的化学反应

<Descriptions.Item label="测试文本行" contentStyle={{ width: 1 }}>

Typography与Description的化学反应

方案二

有没有更优雅的方式?

让我们把视线的焦点从单行文本转移到content身上。

已知,当我们不给content设置宽度的时候,content的宽度会随着单行文本内容的增加而增加。

单行文本内容的父元素content的宽度是动态变化,它的overflow束手无策。

但是还有一位角色,它的宽度是固定的,它就是content的父元素。

那么我们就可以给content设置overflow: 'hidden',因为其实content对于它的父元素是属于超出容器的,

因此通过给content设置overflow: 'hidden',将它超出父元素的内容进行隐藏,这就使得content的宽度变成了父元素的宽度,间接地给了content一个具体的宽度,于是单行文本内容的overflow: 'hidden'也就能够生效了。

<Descriptions.Item label="测试文本行" contentStyle={{ overflow: 'hidden' }}>

Typography与Description的化学反应

转载自:https://juejin.cn/post/7367236229291376666
评论
请登录