写点什么

Threads 横空出世,通过解析 App,我发现了这些 CSS 小秘密

作者 | Ahmad, Digital

  • 2023-08-11
    北京
  • 本文字数:2563 字

    阅读完需:约 8 分钟

Threads 横空出世,通过解析App,我发现了这些CSS小秘密

每当遇上一款新产品,我首先想到的就是研究研究他们是怎么实现 CSS 的。Meta 新近推出的 Threads 当然也不例外,我快速体验了这款移动应用,发现它的主要功能就是展示网络上的公共发帖。

 

浏览过程中我也有了其他深入发现,本文将具体为大家一一介绍。

 

闲言少叙,咱们马上开始!

 

在帖子布局中使用 CSS 网格

 

Threads 当中的 CSS 网格,可以算是我在生产级应用中见到的最值得一聊的案例。Meta 在这里选择用 CSS 网格构建帖子布局。

 


咱们简单看看:

 

: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;}
复制代码

 

有趣发现:第一个网格列被命名为--barcelona。我很好奇他们为什么要选这个名字。

帖子布局由 2 列 x 4 行网格组成。这里没有主容器,帖中的每个条目封镜 使用 grid-column 和 grid-row 属性进行手动放置。

 

再来看用户头像:

 

.post-avatar {  padding-top: 4px;  grid-row: 1 / span 2;  grid-column: 1;}
复制代码

 

头像位于第一列并跨越前两行。这里的 padding-top 尤其值得注意。虽然我在生产代码中没找到确切用途,但猜测它可能是在微调 UI 对齐。

 

下图所示,是经过/未经 padding-top 处理的头像部分前后对比:



在这里采用 padding-top 的另一个理由,可能是要把头像下推以对齐第二行的下沿。



在网格行数中使用奇数值

 

为什么行值选择的是 21px 和 19px?经过进一步检查,这似乎也是对 UI 的微调措施。行高之和为 40px,即头像高度再加上 padding-top(36 像素+4 像素)。



大家可能会好奇,为什么不对这些值做标准化设置?毕竟在系统设计中存在这样一条“铁律”:设计师必须始终遵循 UI 元素的预定义规则。

 

但从 Threads 来看,手动调整具体值也是可接受的。在某些情况下,甚至不妨先把严格的指导方针放下。

 

使用固定的行大小限制

 

由于行大小是固定的,因此无法为其添加填充。但只要意识到存在这个限制,我们也可以借用边距来绕过这一约束。

 

请看以下示例: 



由于行大小是固定的,所以添加顶部和底部填充不会影响到帖子标题。

 

各布局列之间的列距显得有点凌乱

 

布局列之间的当前列距为零。相反,图像大小为 36 x 36 像素,而其容器宽度则为 48 像素。



这就用模拟的方式呈现出了列距的效果。我不知道开发团队为什么不直接设置列距,我个人是比较倾向这种作法。

 

为什么不用命名 CSS 网格区域?

 

根据我迄今为止观察到的情况,网格布局当中存在三种变体,而且使用命名网格区域后这三种变体都能获得效果提升。


我试着复制了这套网格并根据命名区域进行了构建,新的结果比直接为列和行指定值更加顺畅易读。

为了演示差别,我们先为布局中的各个条目分配一个 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";}
复制代码

 

请注意,这里使用 . 来表示空白区域。

 

变体 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";}
复制代码

 

在这里使用命名网格区域,即可通过编辑一处来变更整个布局。

 

Thread Lines 中的 SVG

 

老实说,Threads 应用中最先引起我注意的就是这条螺旋线。从几周前第一次看到以来,我一直想搞清楚它是怎么实现的。

 

先来看以下截屏:



Threads Line 这条螺旋线把我的头像和 Zuck 的头像连接了起来,而这其实是条 SVG 路径,具体由三部分组成。



第一部分的长度用 JavaScript 代码计算得出。

 

CSS 网格的内联 CSS 变量

 

这是个令人振奋的发现:我和其他很多从业者所提倡的设计,终于开始在 Threads 这类大型应用中得到体现。

 

在用户个人资料部分,选项卡的网格布局是由包含选项卡计数的内联 CSS 变量构建而成。



这种设计非常精妙。随着选项卡数量的增加,我们只需要调整 CSS 变量的值即可。多么简洁、多么方便!

 

Overflow Wrapping

 

我注意到,Threads 在帖子本体中用到了 overflow-wrap: anywhere。有一说一,我之前从来没用过、甚至没听说过这个关键字,我一直用的都是 break-word。

 

根据 MDN 的介绍,它跟 break-word 的作用相同,只有一点区别:在计算最小内容的实际大小时,它会考虑由单词截断造成的软换行情况。

 

我还是没发现 break-word 跟 anywhere 到底有什么区别。如果有 Threads 团队的同学正好看到这篇文章,还望不吝赐教。

 

使用动态视口单元

 

我很喜欢用动态视口单元 dvh 作为启动画面。



感兴趣的朋友也可以参考我之前写的关于新视口单元的文章:

 

https://ishadeed.com/article/new-viewport-units/

 

几项防御式 CSS 策略

 

为了确保 Flexbox 的布局不会因最小内容长度而中断,可以使用 min-width: 0 来重置该行为。



我在讨论 Flexbox 中最小内容大小的防御式 CSS 文章中,具体介绍了相关问题。

 

https://defensivecss.dev/tip/flexbox-min-content-size/

 

总结

 

文章就是这些。我很喜欢研究 CSS,以此为切入点思考 Threads 团队是如何设计和构建这款产品的。相信还有很多细节逃过了我的双眼,毕竟目前能接触到的只是 Web 上的预览版本。随着后续研究的深入,我也期待给大家带来更多有趣的发现。

 

原文链接:


https://ishadeed.com/article/threads-app-css/

 

相关阅读:


5 天内用户数破亿、增速碾压 ChatGPT,Twitter 劲敌 Threads 是如何构建的?

nodejs 中使用 worker_threads 来创建新的线程

48 小时注册用户达 7000 万,马斯克:Threads 是 Twitter 前员工做出来的!

我眼中的 CSS 革命:新特性潜力无限

2023-08-11 16:534374

评论

发布
暂无评论
发现更多内容

亚马逊海外直播网络专线的重要性与优势

Ogcloud

直播带货 电商直播 亚马逊 亚马逊直播

STM32入门开发-详解GPIO口的配置与控制方式(以LED灯为例)

DS小龙哥

7月月更

有了小浣熊,办公数据分析不再愁

穿过生命散发芬芳

社区征文 办公小浣熊

SketchUp Pro 2022 for Mac(草图大师)中英文双语 v22.0.353版

Mac相关知识分享

VMware Fusion Pro for mac(vm虚拟机) v13.5.2版

Mac相关知识分享

小智报表实战系列-2 商品销售交叉表

小智数据

任务调度TASKCTL与ETL DataStage融合:打造高效企业数据处理

敏捷调度TASKCTL

ETL任务 TASKCTL ETL数据集成 任务调度平台

WebStorm 2023 for Mac(JavaScript开发工具) v2023.3.2中文版

Mac相关知识分享

扫描全能王AIGC“黑科技”亮相WAIC,《人民日报》、央视、新华社同时“点赞”

合合技术团队

人工智能 OCR AIGC

管理者如何为团队赋能,提升测试效率

测吧(北京)科技有限公司

测试

Luminar Neo for Mac(AI技术图像编辑软件) 1.17.0版

Mac相关知识分享

开发全方位的体育赛事直播娱乐平台,吸引更多用户增强用户粘性

软件开发-梦幻运营部

LeetCode题解:2319. 判断矩阵是否是一个 X 矩阵,JavaScript,详细注释

Lee Chen

小智报表实战系列-3 分栏报表

小智数据

数据集与数据库的差异

蛙人族

BSC链近况及解读:BSC链代币DApp开发详解

区块链软件开发推广运营

dapp开发 区块链开发 链游开发 NFT开发 公链开发

【YashanDB知识库】YAS-02024 lock wait timeout, wait time 0 milliseconds

YashanDB

yashandb 崖山数据库

Rhinoceros 8 for Mac(犀牛8 mac版) v8.2.23346.13002版

Mac相关知识分享

DevSecOps在数字政府建设中的实践研究

EquatorCoco

DevOps 运维 低代码 网络

探索AI人才培养新范式,合合信息与同济大学软件学院签署产教融合人才培养协议

合合技术团队

合合信息 校企合作 #人工智能 同济大学

Introducing Wallys' Peacock: The Ultimate Industrial-Grade WiFi 6 Dual-Band Wireless Bridge - AVAILABLE NOW

wallyslilly

FASTROAMING 快速漫游 agv机器人

Alfred 5 for Mac(mac应用快速启动器)v5.1.4 (2195)中/英版

Mac相关知识分享

iStat Menus for Mac(系统活动监控器) v6.73 (1230)中文版

Mac相关知识分享

Final Cut Pro X for Mac(fcpx专业多媒体剪辑软件) v10.4.9特别版

Mac相关知识分享

Socks5代理为什么比HTTP代理快?

IPIDEA全球HTTP

代理IP http代理 socks5代理

解读jd.item_search_img API返回值:京东按图搜索的智能匹配

技术冰糖葫芦

API 安全 API 文档 API 开发 API 协议

利用SpringBoot+rabbitmq 实现邮件异步发送,保证100%投递成功

快乐非自愿限量之名

spring Spring Boot 邮件

关于ComfyUI的一些Tips

不在线第一只蜗牛

人工智能 AI

JetBrains GoLand For Mac(GO语言集成开发工具环境)v2024.1.4 版

Mac相关知识分享

如何让大模型更聪明

蛙人族

大数据‘’ Data Center

云原生NPM数据采集和指标计算方法

乘云数字DataBuff

云原生 npm

Threads 横空出世,通过解析App,我发现了这些CSS小秘密_大前端_InfoQ精选文章