我們是袋鼠雲數棧 UED 團隊,致力於打造優秀的一站式數據中台產品。我們始終保持工匠精神,探索前端道路,為社區積累並傳播經驗價值。 本文作者:修能 What's? 數棧產品里的 Descriptions 組件實際上就是 antd 的 Descriptions 組件,那麼 antd 的 Descrip ...
我們是袋鼠雲數棧 UED 團隊,致力於打造優秀的一站式數據中台產品。我們始終保持工匠精神,探索前端道路,為社區積累並傳播經驗價值。
本文作者:修能
What's?
數棧產品里的 Descriptions 組件實際上就是 antd 的 Descriptions 組件,那麼 antd 的 Descriptions 組件是什麼?
在數棧產品中,我們通常使用的方式是 bordered + small 的模式。
即:
<Descriptions bordered size="small">
<Descriptions.Item label="任務名稱">
{taskName}
</Descriptions.Item>
<Descriptions.Item label="指標表名稱">
{tableName}
</Descriptions.Item>
</Descriptions>
展示如下:
平平無奇,甚至非常普通。但,這裡面暗藏玄機。
Why?
我們要實現一行只有一個 Item 的設計方式。這裡我們可以藉助 Descriptions 組件的 column API 實現。
- <Descriptions bordered size="small">
+ <Descriptions bordered size="small" column={1}>
此時,一位靚仔發出疑惑:“怎麼就這麼寬了?”
那麼,直接根據設計稿的尺寸給設置寬度吧
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
- 大數據分散式任務調度系統——Taier
- 輕量級的 Web IDE UI 框架——Molecule
- 針對大數據領域的 SQL Parser 項目——dt-sql-parser
- 袋鼠雲數棧前端團隊代碼評審工程實踐文檔——code-review-practices
- 一個速度更快、配置更靈活、使用更簡單的模塊打包器——ko
- 一個針對 antd 的組件測試工具庫——ant-design-testing