Typography与Description的化学反应
前情提要
在公司的日常需求开发中,遇到了一个问题,借此文章分享一下(文章中的配图都是通过demo复现的,不方便直接截图公司的网页)~
- 在
Description
组件中使用Typography.Text
组件,开启ellipsis
。 - 在
Description
组件中使用Typography.Paragraph
组件,也开启ellipsis
。
我们期望的结果
页面实际的结果
我的反应
为什么在别的页面的详情页,同样的组合方式就不会有这个问题?
Ant Design 的反应
直入主题
组件结构
控制变量法
1.Descriptions.Item中包裹的内容不同
是否是Typography.Text 和 Typography.Paragraph对于溢出省略处理的方式不同,导致的最后展示结果不同?
Typography.Text的处理方式
代码展示
.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-space
、 overflow
配套使用?
text-overflow 属性并不会强制“溢出”事件的发生,因此为了能让文本能够溢出容器,你需要在元素上添加几个额外的属性:overflow 和 white-space。 —— MDN
Why white-space:nowrap
?
当文本超过指定容器宽度时,如果没有 white-space: nowrap; 属性,文本会自动换行,此时也就不会溢出当前容器了。
所以,white-space: nowrap; 属性的作用就是为了限制文本在一行内显示,这样当文本超过指定容器宽度时,不会自动换行而是溢出容器。
Why overflow:hidden
?
white-space: nowrap帮助我们创造了文本溢出容器的条件,而设置overflow:hidden则是帮助我们设置了元素溢出时所需的行为,即隐藏 溢出的内容。
至此,text-overflow
的作用说明中(“用于确定如何提示用户存在隐藏的溢出内容”)提到的两个前置条件均被满足,于是它能够生效了。
Typography.Paragraph的处理方式
代码展示
.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等,其他浏览器可能不支持。此外,由于这种方式是非标准的私有属性,还有可能被未来的浏览器或版本所废弃。
思考分析
- content给自己设置了
flex:1
的css属性,其中没有设置flex-basis
。flex: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。
<Descriptions.Item label="测试文本行" contentStyle={{ width: 1 }}>
方案二
有没有更优雅的方式?
让我们把视线的焦点从单行文本转移到content身上。
已知,当我们不给content设置宽度的时候,content的宽度会随着单行文本内容的增加而增加。
单行文本内容的父元素content的宽度是动态变化,它的overflow束手无策。
但是还有一位角色,它的宽度是固定的,它就是content的父元素。
那么我们就可以给content设置overflow: 'hidden'
,因为其实content对于它的父元素是属于超出容器的,
因此通过给content设置overflow: 'hidden'
,将它超出父元素的内容进行隐藏,这就使得content的宽度变成了父元素的宽度,间接地给了content一个具体的宽度,于是单行文本内容的overflow: 'hidden'
也就能够生效了。
<Descriptions.Item label="测试文本行" contentStyle={{ overflow: 'hidden' }}>
转载自:https://juejin.cn/post/7367236229291376666