深挖 Threads App 帖子布局,我进一步加深了对CSS网格布局的理解

6febbd7b210eae2766ac4a0fc83aa746.jpeg

ed8b6e24229e73b41a20e3958260411b.png

当我遇到一个新产品时,我首先想到的是他们如何实现CSS。当我遇到Meta的Threads时也不例外。我很快就探索了移动应用程序,并注意到我可以在网页上预览公共帖子。

这为我提供了一个深入挖掘的机会。我发现了一些有趣的发现,我将在本文中讨论。

让我们深入了解吧!

使用CSS Grid进行帖子布局

在生产应用程序中,CSS Grid的最显着的用例之一就是Threads。CSS Grid用于构建帖子布局。

看一下:

6b492f4f6f981e2a11fad258f92bb90e.png

: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列* 4行网格组成。没有主容器;使用grid-column和grid-row属性手动放置帖子中的每个项目

用户头像

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

头像位于第一列中,跨越了前两行。值得注意的是存在padding-top。虽然我在生产代码中找不到具体原因,但它似乎是对UI对齐进行微调。

这是带有和不带有padding-top处理的头像的前后外观:

2924d468cef762f88b5c1c152753fa84.png

应用padding-top的另一个原因可能是将头像下移并使其更接近线条。

dfd6d203e0066efc31b6b6c8a134ada7.png

对网格行使用奇数值

奇数值作为网格行的高度是出于什么考虑?经过进一步检查,似乎是对用户界面进行微调的一种方式。行高的总和为40px,这包括头像的高度和padding-top(36px + 4px)。

5cba05d7e748266a3ad9a27bfc6ddb83.png

可能会好奇为什么这些值没有标准化。设计系统通常被认为是设计师必须严格遵循预定义的UI元素规则的信仰。

然而,这个例子表明,使用手动调整的值是可以接受的。在某些情况下,从严格的准则中偏离是可以接受的。

使用固定大小行的限制

由于前两行的固定宽度,无法向它们添加填充。然而,只要您意识到这个限制,就可以通过使用边距来解决。

以下是一个例子:

24b55000c166e23933c91ebad3373ce0.png

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

 布局列之间的空间感觉有点乱

目前布局列之间的间隔为零。相反,图像的大小为36 * 36像素,而其容器的宽度为48像素。

734086cbe1fbbc1068c9a4d622d02919.png

这样可以模拟这里的间距。我不知道为什么团队会选择这种方法,但我更喜欢使用gap属性。

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

根据我目前观察到的情况,有三种网格布局变体,它们都可以受益于使用命名网格区域。

我尝试复制网格并基于命名区域构建它。与指定列和行的值相比,它看起来更容易扫描。

为了证明这一点,让我们为布局中的每个项目分配一个grid-area:

.AvatarContainer {
  grid-area: avatar;
}

.HeaderContainer {
  grid-area: header;
}

.BodyContainer {
  grid-area: body;
}

.ThreadlineContainer {
  grid-area: line;
}

.FooterContainer {
  grid-area: footer;
}

方式一:默认

825ecca8f7833c2a34612706a44e03f0.png

.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:回复

变化是指某人回复另一个人的情况。

1a660b1035c2d83b85184f9051802714.png

.post--reply {
  grid-template-rows: 36px 0 max-content max-content;
  grid-template-areas:
    "avatar header"
    "body body"
    "body body"
    "footer footer";
}

变化3:螺纹连接细线

337f95b3588108a851d0ed143a2f4e06.png

.post--withLine {
  grid-template-areas:
    "avatar header"
    "avatar body"
    "line body"
    "footer footer";
}

这里使用命名网格区域使得只需在一个地方进行编辑就可以更改布局。

SVG细线处理

说实话,最初吸引我注意的是Threads应用程序中的线条。我对它的构造方式感到好奇,因为几周前我曾写过一个类似的主题。

请参见下图:

d320398ca5534a4c8f46e383fac5f409.png

连接我的头像和马克的头像的那条线是一条 SVG 路径。它由三部分组成。

b26cdd78ad26fc2f2c9d37554d44b94a.png

第一部分的长度是用 JavaScript 计算的。

网格的内联CSS变量

我很高兴看到像Threads这样的大型应用程序正在使用我和许多其他人提倡的东西。

在用户个人资料中,选项卡网格布局是使用包含选项卡数的内联CSS变量构建的。

81a8d5dd57aeaca22c77cd0cc54d558c.png

很有用。当选项卡数量增加时,我们只需要更改CSS变量的值。很简洁,对吧?

溢出换行

我注意到在帖子正文中使用了overflow-wrap: anywhere。我以前没有使用过或听说过这个关键词。我使用break-word。

根据MDN的说法,它与break-word相同,但有一个额外的东西:

计算最小内容内在大小时,考虑了单词折断引入的软换行机会。

我仍然没有发现使用break-word和anywhere之间的区别。如果Threads团队中有任何人正在阅读这篇文章,我非常好奇为什么。

动态视口单位的使用

我喜欢在启动画面中使用动态视口单位dvh。

1e07f6d9e37dc7c539674d03506ff91a.png

防御性的CSS策略

为了确保flexbox布局不会因为最小内容长度而破裂,使用min-width: 0来重置该行为。

0ac1c07faabfb57302109ac0527d58aa.png

结论

今天就到这里。我喜欢检查CSS并了解Threads团队如何构建产品。我相信还有很多东西我没有注意到,因为这只是Web上的预览版本。

由于文章内容篇幅有限,今天的内容就分享到这里,文章结尾,我想提醒您,文章的创作不易,如果您喜欢我的分享,请别忘了点赞和转发,让更多有需要的人看到。同时,如果您想获取更多前端技术的知识,欢迎关注我,您的支持将是我分享最大的动力。我会持续输出更多内容,敬请期待。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/62723.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

24届近5年重庆邮电大学自动化考研院校分析

今天给大家带来的是重庆邮电大学控制考研分析 满满干货~还不快快点赞收藏 一、重庆邮电大学 学校简介 重庆邮电大学简称"重邮",坐落于直辖市-重庆市,入选国家"中西部高校基础能力建设工程”、国家“卓越工程师教育培养计划…

java的StringBuffer类和StringBuilder类

目录 StringBufferStringBuffer简介StringBuffer类的继承关系StringBuffer类的底层实现创建StringBuffer对象StringBuffer类的常用方法 StringBuilderStringBuilder简介 StringBuffer StringBuffer简介 StringBuffer对象是一个字符序列可变的字符串(String类不可变)。它和Str…

Java中Integer方法

先进行专栏介绍 本专栏是自己学Java的旅途,纯手敲的代码,自己跟着黑马课程学习的,并加入一些自己的理解,对代码和笔记 进行适当修改。希望能对大家能有所帮助,同时也是请大家对我进行监督,对我写的代码进行…

springboot快速整合Memcached缓存技术

目录 Memcached基本介绍 Memcached安装 springboot技术整合 规范化定义配置属性 Memcached基本介绍 memcached是一套分布式的快取系统,与redis相似,当初是Danga Interactive为了LiveJournal所发展的,但被许多软件(如MediaWiki&#xff…

道本科技受邀参加建筑产业互联网推动建筑产业现代化体系构建座谈会,以数字化产品为建筑行业注入新动能!

2023年7月底,道本科技作为中国建筑业协会合作伙伴,受邀参加了建筑产业互联网推动建筑产业现代化体系构建座谈会。在这次座谈会上,道本科技旗下产品“合规数”“合同智能审查”和“智合同范本库”被中国建筑(中小企业)产…

【笔记】第94期-冯永吉-《湖仓集一体关键技术解读》-大数据百家讲坛-厦大数据库实验室主办20221022

https://www.bilibili.com/video/BV1714y1j7AU/?spm_id_from333.337.search-card.all.click&vd_sourcefa36a95b3c3fa4f32dd400f8cabddeaf

后端进阶之路——万字总结Spring Security与数据库集成实践(五)

前言 「作者主页」:雪碧有白泡泡 「个人网站」:雪碧的个人网站 「推荐专栏」: ★java一站式服务 ★ ★前端炫酷代码分享 ★ ★ uniapp-从构建到提升★ ★ 从0到英雄,vue成神之路★ ★ 解决算法,一个专栏就够了★ ★ 架…

JavaScript-DOM

目录 DOM 访问节点 节点信息 操作节点 DOM DOM:Document Object Model( 文档对象模型) 访问节点 使用 getElement系列方法访问指定节点 getElementById()、getElementsByName()、getElementsByTagName()根据层次关系访问节点 节点属性 属…

jmeter使用步骤

jmeter 使用步骤 1,进入jmeter目录中的bin目录,双击jmeter.bat 打开 2,右键test plan 创建线程组 3,配置线程组参数 4,右键刚刚创建的线程组,创建请求,填写请求地址 5,需要携带to…

AI让分子“起死回生”:拯救抗生素的新希望

生物工程师利用人工智能(AI)使分子“起死回生”[1]。 为实现这种分子“复活”,研究人员应用计算方法对来自现代人类(智人)和我们早已灭绝的远亲尼安德特人和丹尼索瓦人的蛋白质数据进行分析。这使研究人员能够鉴定出可以杀死致病细菌的分子,从而促进研发用于治疗人类…

11. 使用tomcat中碰到的一些问题

文章目录 问题一:Tomcat的startup.bat启动后出现乱码问题二:一闪而退之端口占用问题三:非端口问题的一闪而退问题四:服务器的乱码和跨域问题问题五: 在tomcat\webapps\下创建文件夹为什么tomcat重启就会丢失问题六:Tom…

大后台,小前台——组合式创新加速推进产教融合

2023年8月1日,由成都知了汇智科技有限公司组织召开的“2023产教融合项目推进闭门研讨会”于成都市高新区软件园G8区7楼正式举行,本次会议基于“产业链的用人需求、资本链的回报诉求、服务链的价值要求、教育链的延伸需求”进行交流探讨,形成稳…

区块链实验室(17) - FISCO BCOS的P2P网络层分析

首先启动FISCO BCOS的示例网络,即4个节点的强连通网络。每个节点与其余3个节点存在网络连接。 打开控制台,可以看到当前有21个区块。 其中1个节点的P2P端口是30301,监测这个节点的端口。 该端口的部分流量见下图所示。白底部分是某1秒钟接收到…

【雕爷学编程】Arduino动手做(184)---快餐盒盖,极低成本搭建机器人实验平台

吃完快餐粥,除了粥的味道不错之外,我对个快餐盒的圆盖子产生了兴趣,能否做个极低成本的简易机器人呢?也许只需要二十元左右 知识点:轮子(wheel) 中国词语。是用不同材料制成的圆形滚动物体。简…

Java源码解析-重点集合框架篇

Java 源码解析,集合篇 一:故事背景二:数据结构2.1 线性结构2.2 非线性结构 三:集合分类3.1 结构图 三:详细分析3.1 List3.1.1 ArrayList3.1.1.1 底层结构3.1.1.2 主要特点 3.1.2 LinkedList3.1.2.1 底层结构3.1.2.2 主…

简单易懂的Transformer学习笔记

1. 整体概述 2. Encoder 2.1 Embedding 2.2 位置编码 2.2.1 为什么需要位置编码 2.2.2 位置编码公式 2.2.3 为什么位置编码可行 2.3 注意力机制 2.3.1 基本注意力机制 2.3.2 在Trm中是如何操作的 2.3.3 多头注意力机制 2.4 残差网络 2.5 Batch Normal & Layer Narmal 2.…

VBA技术资料MF40:VBA_计数筛选状态的数据行数

【分享成果,随喜正能量】人唯有与喜欢的事物发展关系,不管是人或者是物还是事,包括喜欢自己外表、个性的部分,喜欢自己做的事,喜欢自己的创造,喜欢的风景……才给人带来对自己的认同。在与喜欢的事物互动关…

yolo-v5学习(使用yolo-v5进行安全帽检测错误记录)

常见错误 跑YOLOv5遇到的问题_runtimeerror: a view of a leaf variable that requi_Pysonmi的博客-CSDN博客 python train.py --img 640 --batch 16 --epochs 10 --data ./data/custom_data.yaml --cfg ./models/custom_yolov5.yaml --weights ./weights/yolov5s.pt 1、梯度…

C# 简单模拟 程序内部 消息订阅发布功能

文章目录 前言模拟消息订阅发布使用注意事项 前言 我想做个简单的消息发布订阅功能,但是发现好像没有现成的工具类。要么就是Mqtt这种消息订阅发布。但是我只想程序内部进行消息订阅发布,进行程序的解耦。那没办法了,只能自己上了 模拟消息…

【LeetCode】094. 分割回文串II

文章目录 1. 解题思路1.1 创建dp表1.2 状态转移方程1.3 提前求出所有子串是否是回文串 2. 整体代码 1. 解题思路 1.1 创建dp表 这道题我们使用动态规划的方法来解,首先创建一个大小为字符串长度的dp表。dp[i] 表示 s[0, i] 的字符串最小划分多少次可以全划分为回文…