浅谈数栈产品里的 Descriptions 组件

我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品。我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值。
本文作者:修能

What's?

数栈产品里的 Descriptions 组件实际上就是 antd 的 Descriptions 组件,那么 antd 的 Descriptions 组件是什么?

在数栈产品中,我们通常使用的方式是 bordered + small 的模式。

即:

tsx 复制代码
<Descriptions bordered size="small">
  <Descriptions.Item label="任务名称">
    {taskName}
  </Descriptions.Item>
  <Descriptions.Item label="指标表名称">
    {tableName}
  </Descriptions.Item>
</Descriptions>

展示如下:

平平无奇,甚至非常普通。但,这里面暗藏玄机。

Why?

我们要实现一行只有一个 Item 的设计方式。这里我们可以借助 Descriptions 组件的 column API 实现。

diff 复制代码
 - <Descriptions bordered size="small">
 + <Descriptions bordered size="small" column={1}>

此时,一位靓仔发出疑惑:"怎么就这么宽了?"

那么,直接根据设计稿的尺寸给设置宽度吧

tsx 复制代码
contentStyle={{
  width: 630,
}}
labelStyle={{
  width: 140,
}}

可以?**不可以!**由于我们这个模块是在详情的抽屉里,抽屉的宽度是不固定的,那么这里设置固定值会导致有问题!......有问题吧?

这里的 label 宽度并没有按照所设置的来,而是自适应的撑满了。

但是,都是自适应,这里的自适应并不是我们想要的,根据 UI 设计师的确认,这里的自适应应该是 label 的大小不变,content 的大小自适应。


怎么实现?

设置 contentStyle 的 width 为 'calc(100% - 140px)'


看起来,这个需求搞定了?实际上,还有问题!

这里,我们需要模拟一下任务名称很长并且用 Button 组件的情况。

这里,我们想到,可以用 EllipsisText 组件解决溢出省略的问题。

糟糕,貌似并没有生效,这是为何?


分析原因如下:

这里我们一下原因,首先,我们这里的省略逻辑是如下

通过设置 maxWidth 为百分比(不能设置具体数值,为何?),然后配合 overflow

我们从 DOM 树上可以看出来,理论上,我们应该是 td 元素的宽度百分比,同时 td 元素设置的宽度也是百分比,所以理论上是 tr 元素的百分比。


这里我们发现,tr 元素的宽度并没有按照我们设想的是继承父元素的宽度,而是被子元素撑开了。那么,我们尝试在 tr 上增加 width:100% 使其宽度为继承父元素的宽度。

还是无效,这是为何?


我们这里注意到,width 是需要继承父元素的宽度,而父元素的宽度也是被撑开的。这里我们省略一些定位的过程,快进到定位 table 元素。

这个 Descriptions 组件的根元素是 table 元素。table 元素相比起普通的 div 元素来说,更加复杂,其相关的 CSS 属性更加难以捉摸。


观察到,这里的 table 组件上有如下属性

table 的宽度被设置了 100%,但是并没有继承父元素的宽度,而是被子元素撑开了。

这里我们注意到 table 有一条属性为 table-layout,在 MDN 中该属性的定义为:

table-layout CSS 属性定义了用于布局表格的单元格、行和列的算法。

如果设置为 auto,则表示

默认情况下,大多数浏览器使用自动表格布局算法。表格及其单元格的宽度会根据内容自动调整大小。


到这里就破案了,如果设置为了 auto,则单元格会根据内容自适应,那么就会导致父元素(即单元格)会被子元素的宽度撑开,即使给父元素的宽度设置了一个固定值也会失效。

如果表格布局是 auto,表格将会根据其内容自动扩展大小,而不考虑指定的 width

那么,可以确认,如果我们想要用 Descriptions 组件实现文案的省略,则不可避免地需要将 table-layout 设置为 fixed 属性。

How

然而,Descriptions 组件默认的 table-layout 是为 auto,且并没有相关的属性去修改这个值。

所以这里我们只能通过全局的 CSS 去修改?(theme 可做)

但这里,我选择在指标里重写 Descriptions 组件,让用户可控地去使用 Descriptions 组件。


题外话,需要插入说明一下,如果 table-layout 设置为 auto,且单元格的内容并没有溢出,即一开始设置的那样子。那么此时单元格的宽度其实并非我们设置的值,而是基于我们给不同单元格设置的 width 计算出的比例进行等比放大或缩小。

例如:我现在给单元格分别设置 140px 和 280px。

此时若 table 宽度恰好为 420px,则 label(即 th 元素)恰好为 140px,content(即 td 元素)恰好为 280px。

若 table 宽度大于 420px,则按照 1:2 的方式等比放大。

此时 table 的宽度为:

计算可得:806 * 1/3 ≈ 248。

最后

欢迎关注【袋鼠云数栈UED团队】~

袋鼠云数栈 UED 团队持续为广大开发者分享技术成果,相继参与开源了欢迎 star

相关推荐
dualven_in_csdn1 小时前
搞了两天的win7批处理脚本问题
java·linux·前端
你的人类朋友2 小时前
✍️【Node.js程序员】的数据库【索引优化】指南
前端·javascript·后端
小超爱编程3 小时前
纯前端做图片压缩
开发语言·前端·javascript
应巅3 小时前
echarts 数据大屏(无UI设计 极简洁版)
前端·ui·echarts
萌萌哒草头将军3 小时前
🚀🚀🚀什么?浏览器也能修改项目源文件了?Chrome 团队开源的超强 Vite 插件!🚀🚀🚀
vue.js·react.js·vite
Jimmy3 小时前
CSS 实现描边文字效果
前端·css·html
islandzzzz4 小时前
HMTL+CSS+JS-新手小白循序渐进案例入门
前端·javascript·css·html
Senar4 小时前
网页中如何判断用户是否处于闲置状态
前端·javascript
很甜的西瓜4 小时前
typescript软渲染实现类似canvas的2d矢量图形引擎
前端·javascript·typescript·图形渲染·canvas
Allen Bright5 小时前
【CSS-9】深入理解CSS字体图标:原理、优势与最佳实践
前端·css