Threads 橫空出世,通過解析 App,我發(fā)現(xiàn)了這些 CSS 小秘密(解析工具官網(wǎng))
作者 | Ahmad, Digital
譯者 | 核子可樂
策劃 | 丁曉昀
每當遇上一款新產(chǎn)品,我首先想到的就是研究研究他們是怎么實現(xiàn) CSS 的。Meta 新近推出的 Threads 當然也不例外,我快速體驗了這款移動應用,發(fā)現(xiàn)它的主要功能就是展示網(wǎng)絡上的公共發(fā)帖。
瀏覽過程中我也有了其他深入發(fā)現(xiàn),本文將具體為大家一一介紹。
閑言少敘,咱們馬上開始!
在帖子布局中使用 CSS 網(wǎng)格
Threads 當中的 CSS 網(wǎng)格,可以算是我在生產(chǎn)級應用中見到的最值得一聊的案例。Meta 在這里選擇用 CSS 網(wǎng)格構建帖子布局。
咱們簡單看看:
:root { --barcelona-threadline-column-width: 48px;}.post { display: grid; grid-template-columns: var(--barcelona-threadline-column-width) minmax(0, 1fr); grid-template-rows: 21px 19px max-content max-content;}
復制代碼
有趣發(fā)現(xiàn):第一個網(wǎng)格列被命名為–barcelona。我很好奇他們?yōu)槭裁匆x這個名字。
帖子布局由 2 列 x 4 行網(wǎng)格組成。這里沒有主容器,帖中的每個條目封鏡 使用 grid-column 和 grid-row 屬性進行手動放置。
再來看用戶頭像:
.post-avatar { padding-top: 4px; grid-row: 1 / span 2; grid-column: 1;}
復制代碼
頭像位于第一列并跨越前兩行。這里的 padding-top 尤其值得注意。雖然我在生產(chǎn)代碼中沒找到確切用途,但猜測它可能是在微調(diào) UI 對齊。
下圖所示,是經(jīng)過/未經(jīng) padding-top 處理的頭像部分前后對比:
在這里采用 padding-top 的另一個理由,可能是要把頭像下推以對齊第二行的下沿。
在網(wǎng)格行數(shù)中使用奇數(shù)值
為什么行值選擇的是 21px 和 19px?經(jīng)過進一步檢查,這似乎也是對 UI 的微調(diào)措施。行高之和為 40px,即頭像高度再加上 padding-top(36 像素 4 像素)。
大家可能會好奇,為什么不對這些值做標準化設置?畢竟在系統(tǒng)設計中存在這樣一條“鐵律”:設計師必須始終遵循 UI 元素的預定義規(guī)則。
但從 Threads 來看,手動調(diào)整具體值也是可接受的。在某些情況下,甚至不妨先把嚴格的指導方針放下。
使用固定的行大小限制
由于行大小是固定的,因此無法為其添加填充。但只要意識到存在這個限制,我們也可以借用邊距來繞過這一約束。
請看以下示例:
由于行大小是固定的,所以添加頂部和底部填充不會影響到帖子標題。
各布局列之間的列距顯得有點凌亂
布局列之間的當前列距為零。相反,圖像大小為 36 x 36 像素,而其容器寬度則為 48 像素。
這就用模擬的方式呈現(xiàn)出了列距的效果。我不知道開發(fā)團隊為什么不直接設置列距,我個人是比較傾向這種作法。
為什么不用命名 CSS 網(wǎng)格區(qū)域?
根據(jù)我迄今為止觀察到的情況,網(wǎng)格布局當中存在三種變體,而且使用命名網(wǎng)格區(qū)域后這三種變體都能獲得效果提升。
我試著復制了這套網(wǎng)格并根據(jù)命名區(qū)域進行了構建,新的結果比直接為列和行指定值更加順暢易讀。
為了演示差別,我們先為布局中的各個條目分配一個 grid-area:
.AvatarContainer { grid-area: avatar;}.HeaderContainer { grid-area: header;}.BodyContainer { grid-area: body;}.ThreadlineContainer { grid-area: line;}.FooterContainer { grid-area: footer;}
復制代碼
變體 1:使用默認值
之后,我們再來研究變體。以下為默認布局的效果:
.post { display: grid; grid-template-columns: var(--barcelona-threadline-column-width) minmax(0, 1fr); grid-template-rows: 21px 19px max-content max-content; grid-template-areas: "avatar header" "avatar body" ". body" ". footer";}
復制代碼
請注意,這里使用 . 來表示空白區(qū)域。
變體 2:回復
這個變體代表某人回復另一用戶時的情況。
.post--reply { grid-template-rows: 36px 0 max-content max-content; grid-template-areas: "avatar header" "body body" "body body" "footer footer";}
復制代碼
變體 3:默認值加 Thread Line
.post--withLine { grid-template-areas: "avatar header" "avatar body" "line body" "footer footer";}
復制代碼
在這里使用命名網(wǎng)格區(qū)域,即可通過編輯一處來變更整個布局。
Thread Lines 中的 SVG
老實說,Threads 應用中最先引起我注意的就是這條螺旋線。從幾周前第一次看到以來,我一直想搞清楚它是怎么實現(xiàn)的。
先來看以下截屏:
Threads Line 這條螺旋線把我的頭像和 Zuck 的頭像連接了起來,而這其實是條 SVG 路徑,具體由三部分組成。
第一部分的長度用 JavaScript 代碼計算得出。
CSS 網(wǎng)格的內(nèi)聯(lián) CSS 變量
這是個令人振奮的發(fā)現(xiàn):我和其他很多從業(yè)者所提倡的設計,終于開始在 Threads 這類大型應用中得到體現(xiàn)。
在用戶個人資料部分,選項卡的網(wǎng)格布局是由包含選項卡計數(shù)的內(nèi)聯(lián) CSS 變量構建而成。
這種設計非常精妙。隨著選項卡數(shù)量的增加,我們只需要調(diào)整 CSS 變量的值即可。多么簡潔、多么方便!
Overflow Wrapping
我注意到,Threads 在帖子本體中用到了 overflow-wrap: anywhere。有一說一,我之前從來沒用過、甚至沒聽說過這個關鍵字,我一直用的都是 break-word。
根據(jù) MDN 的介紹,它跟 break-word 的作用相同,只有一點區(qū)別:在計算最小內(nèi)容的實際大小時,它會考慮由單詞截斷造成的軟換行情況。
我還是沒發(fā)現(xiàn) break-word 跟 anywhere 到底有什么區(qū)別。如果有 Threads 團隊的同學正好看到這篇文章,還望不吝賜教。
使用動態(tài)視口單元
我很喜歡用動態(tài)視口單元 dvh 作為啟動畫面。
感興趣的朋友也可以參考我之前寫的關于新視口單元的文章:
https://ishadeed.com/article/new-viewport-units/
幾項防御式 CSS 策略
為了確保 Flexbox 的布局不會因最小內(nèi)容長度而中斷,可以使用 min-width: 0 來重置該行為。
我在討論 Flexbox 中最小內(nèi)容大小的防御式 CSS 文章中,具體介紹了相關問題。
https://defensivecss.dev/tip/flexbox-min-content-size/
總結
文章就是這些。我很喜歡研究 CSS,以此為切入點思考 Threads 團隊是如何設計和構建這款產(chǎn)品的。相信還有很多細節(jié)逃過了我的雙眼,畢竟目前能接觸到的只是 Web 上的預覽版本。隨著后續(xù)研究的深入,我也期待給大家?guī)砀嘤腥さ陌l(fā)現(xiàn)。
原文鏈接:
https://ishadeed.com/article/threads-app-css/
版權聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至 舉報,一經(jīng)查實,本站將立刻刪除。