【前端教程】从Facebook的新设计中窥探他们如何运用CSS技巧

image

Photo by Kon Karampelas on Unsplash

来源:https://ishadeed.com/article/new-facebook-css/

作者:Ahmad Shadeed

翻译:前端外文精选

最近,新的Facebook设计开始为用户推出,大约两周前我就收到了,最初,每个UI元素对我来说都有点大,我用了好几天才习惯。在本文中,我将讨论我所看到的所有有趣的事情。

来看看Facebook是怎么运用CSS的吧!

头像使用SVG

image

SVG用于头像图片,例如个人资料照片,您的页面或您所在的组。

<svg role="none" style="height: 36px; width: 36px;">  <mask id="avatar">    <circle cx="18" cy="18" fill="white" r="18"></circle>  </mask>  <g mask="url(#avatar)">    <image x="0" y="0" height="100%" preserveAspectRatio="xMidYMid slice" width="100%" xlink:href="avatar.jpg" style="height: 36px; width: 36px;"></image>    <circle cx="18" cy="18" r="18"></circle>  </g></svg>

我问自己,他们为什么要使用它?这是我的想法:

  • 头像需要有一个内部边界与透明的黑色(10%),使明亮的头像作为一个圆圈出现,即使是完全白色的头像。
  • 无法将嵌入的 box-shadow 添加到HTML <img>。因此,他们使用了SVG来解决它。
  • 为了使图像成为圆形,他们使用了SVG <mask> 和SVG <image> 元素。

正如我所提到的,头像内部的边框对于明亮的图像很有用。这是一个详细显示样机的模型。

image

内边框增加如下:

circle,rect {  stroke-width: 2;  stroke: rgba(0, 0, 0, 0.1);  fill: none;}

如果图像是矩形的,则使用的形状是矩形:

<svg role="none" style="height: 36px; width: 36px;">  <mask id="avatar">    <rect cy="18" fill="white" height="36" rx="8" ry="8" width="36" x="0" y="0"></rect>  </mask>  <g mask="url(#avatar)">    <image x="0" y="0" height="100%" preserveAspectRatio="xMidYMid slice" width="100%" xlink:href="avatar.jpg" style="height: 36px; width: 36px;"></image>    <rect cy="18" fill="white" height="36" rx="8" ry="8" width="36" x="0" y="0"></rect>  </g></svg>

有趣的是,主页Feed中的头像是使用 <img> 和内部透明边框的 <div> 元素构建的。如下:

<div class="avatar-wrapper>  <img class="avatar" width="40" height="40" src="avatar.jpg" width="40" alt="">  <div class="avatar-outline"></div></div>

CSS如下

.avatar-wrapper {  position: relative;}.avatar {  display: block;  border-radius: 50%;}.avatar-outline {  position: absolute;  left: 0;  top: 0;  width: 100%;  height: 100%;  box-shadow: inset 0001pxrgba(0, 0, 0, 0.1);  border-radius: 50%;}

由于SVG技术仅在少数地方使用,我想使用 <img><div> 的原因与页面大小有关。如果将SVG用于Feed头像,则会导致随着用户向下滚动而增加下载的KBs。

使用div间隔代替空白

我当时还不够大,无法住在间隔GIFS时代,但我看到了一些与他们有关的东西。如果可以的话,我将其称为spacer div?

image

我在这里加上一些背景,上面是在主页Feed中随机出现的好友请求部分。有一个人的网格,并且此网格有左边距。通常,我将通过 margin-left:16px 来执行此操作。但是,Facebook添加了<div> 作为容器边缘和网格之间的空间。

我想知道原因是什么?

  • 也许在他们建立的设计系统中,容器元素不允许添加边距?
  • 也许这是一个 react 组件,可以通过指定宽度来在任何地方使用?

为什么没有margin?据我所见,CSS(大约100K行)充满了utility 类,可以很容易地将一个类添加到包装器中以留出空白。

使用CSS过滤器

image

您看到那里的四个图标了吗?加号和箭头是图像,而Messenger和通知则是SVG元素。我不知道这种混合背后的原因是什么。

单击最后一个时,图标颜色变为蓝色。我问自己,当这是一张图片的时候颜色是如何变化的?图像在悬停时可能会更改吗?没有!我注意到有一个CSS过滤器可用于更改图像颜色。

.icon {  filter: invert(39%) sepia(57%) saturate(200%) saturate(200%) saturate(200%) saturate(200%) saturate(200%) saturate(147.75%) hue-rotate(202deg) brightness(97%) contrast(96%)}

是的,这是Facebook.com的生产代码,这对我来说很奇怪。用SVG图标代替它并简单地更改 fill 颜色难吗?

这也用于已验证的帐户图标。

image

并且还用于用户个人资料链接。

.icon {  filter: invert(59%) sepia(11%) saturate(200%) saturate(135%) hue-rotate(176deg) brightness(96%) contrast(94%);}

image

如果您想了解更多有关如何使用CSS滤镜将黑色图像转换为任何颜色的信息,那么此答案[1]非常适合您。

为阴影使用图像

image

这是一个 2px * 14px 的图像,正在被重复。不仅如此,还有一个专用的 <div> 用于该阴影。使用它的目的是什么?

来自Facebook的Royi Hagigi证实,使用图片的原因是为了性能。在浏览器中,像这样的浮动Header上的框阴影会杀死滚动性能。

当Royi Hagigi被问及如何测试时,他回答:“滚动一个充满视频的页面,页面的随机部分会消失和重新出现。这是糟糕的。”

我完全同意。

广泛使用CSS变量

我喜欢他们使用CSS变量。从我所看到的,:root 元素中添加了320多个变量。这些值也用于黑暗模式。

切换暗模式时,会将 __fb-dark-mode 类添加到HTML元素。添加后,它将覆盖 :root 中定义的所有变量,如下所示:

:root {  /* Light模式变量 */  -fds-active-icon:  #3578E5;  --fds-attachment-footer-background:  #F2F3F5;  --fds-blue-05:  #ECF3FF;  --fds-blue-30:  #AAC9FF;  --fds-blue-40:  #77A7FF;}.__fb-dark-mode:root, .__fb-dark-mode {  /* 覆盖light变量 */  --fds-active-icon:  black;  --fds-attachment-footer-background:  black;  --fds-blue-05:  black;  --fds-blue-30:  black;  --fds-blue-40:  black;}

这是class切换时的视频。我建议全屏查看它!

image

行截断(截断多行文本)

image

在侧边栏,有一个链接列表,比如用户简介,最近的,记忆…等。我注意到这里使用了多行文本截断。

.element {  display: -webkit-box;  -webkit-box-orient: vertical;  -webkit-line-clamp: 2;}

上面的样式被添加为内联样式,并且它们也会根据浏览器进行更改。参见下面的模型:

image

浏览器对这个CSS特性的支持非常好。根据CanIUse,所有主流浏览器均支持该功能,但需要带有前缀。

使用Divs的悬停效果

通常,我们在CSS中进行悬停效果。例如,在悬停时需要不同灰色阴影的按钮,我们只需使用以下命令:

.element:hover {  background: #ccc;}

但是,对于像Facebook这样的大型网站,这似乎不切实际。在测试和检查东西的时候,我注意到一个元素,它只在hover上显示,它的主要工作是执行一个hover元素。

.hover-div {  position: absolute;  right: 0;  left: 0;  top: 0;  bottom: 0;  pointer-events: none;  border-radius: 6px;  inset: 4px0px;  background-color: var(--hover-overlay);  transition-property: opacity;  transition-timing-function: var(--fds-animation-fade-out);  cursor: pointer;}

这个元素在JavaScript中被切换,将不 opacity0 更改为 1,所以我对它进行了一些操作,发现它被大量用于许多组件。

有关使用此元素的位置,请参见下面的屏幕截图集合:

image

我喜欢对很多元素使用相同的悬停效果的一致性和简单性。如果这意味着什么,那就是设计语言是一致的,系统是经过精心设计的。做得好,Facebook !

使用inset属性

这是top,right,bottom和left属性的简写。可以这样使用:

.element {  inset: 4px0;  /* 这相当于: top: 4px, bottom: 4px, left: 0, right: 0 */}

inset 属性用于某些元素的悬停div,并以HTML内联方式添加。我在以下组件上注意到了它:

image

在撰写本文时,根据CanIUse,仅Firefox 66+支持 inset

dir =auto和CSS逻辑属性

对于像Facebook这样的多语言网站,有时很难预料内容会是什么样子。例如,post组件中的用户名具有 dir=" auto" 属性。这意味着文本的方向将基于语言。例如,对于英语,它将是从左到右,对于阿拉伯语,它将是从右到左。

除此之外,还有一个内联CSS可以更改文本方向(看起来 dir=auto 是不够的)。

<div dir="auto" style="text-align: start;">محتوى بالعربية</div>

请注意,在元素上添加了 text-align:start。这是一个CSS逻辑属性,等效于 text-align:LTR 布局的权利。

动态封面照片背景

image

你是否注意到有一个渐变,其颜色类似于封面照片中的主要颜色?这是根据封面照片动态添加的。怎么运行的?

1.获得主要颜色

首先,我们需要获取封面照片中占主导地位(最常用)的颜色。该团队创建了一个小的封面照片,只有这种颜色。

image

2.添加使用主色的背景

image

为元素添加的背景来自主色,为了清楚起见,我用白色边框突出显示了封面原始照片。

3.在背景上方添加渐变

.element {  background-image: linear-gradient(to top, #FFFFFF, rgb(255, 255, 255), rgba(255,255,255,0.7), rgba(255,255,255,0.4), rgba(255,255,255,0));}

image

当设计为深色时,渐变从白色变为黑色:

.element {  background-image: linear-gradient(to top, #000, rgb(0, 0, 0), rgba(0,0,0,0.7), rgba(0,0,0,0.4), rgba(0,0,0,0));}

image

提示:你可以使用此工具[2]从图像中获取主色。

多个框阴影

image

我喜欢这个团队为像下拉菜单这样的元素创建阴影的方式,阴影会让你觉得它有深度,而且比普通的阴影要真实得多。

image

.element {  box-shadow: 012px28px0rgba(0, 0, 0, 0.2), 02px4px0rgba(0, 0, 0, 0.1), inset 0001pxrgba(255, 255, 255, 0.5);}

您可能想知道,为什么会有带有50%透明白色的嵌入阴影?好吧,这是在黑暗模式下。请参阅以下有关该插入阴影的缩放图像:

image

聪明,我喜欢它!

Flexbox网格的空元素

我注意到网站上的所有网格都在使用flexbox。有一个引起我注意的是“您的照片”部分。

image

.wrapper {  display: flex;  flex-wrap: wrap;  justify-items: space-between;}.item {  width: 205px;}

听起来不错,对吧?使用 space-between 作为间距是有风险的,因为在只有三张照片的情况下它可能会失败。请参阅下面的样机如何失败:

image

他们如何解决这个问题?好吧,有四个空的 <div> 元素,其宽度等于每张照片。HTML看起来像这样:

<div class="wrapper">  <div class="item"><a href="#"><img src="photo.jpg"></a></div>  <div class="item"><a href="#"><img src="photo.jpg"></a></div>  <div class="item"><a href="#"><img src="photo.jpg"></a></div>  <div class="item"><a href="#"><img src="photo.jpg"></a></div>  <div class="empty"></div>  <div class="empty"></div>  <div class="empty"></div>  <div class="empty"></div></div>

这样,那些空的div将充当假项目,并且它们之间的间距将保持相等。

使用vertical媒体查询

对我来说,很少看到vertical媒体查询的使用。我喜欢他们用它来缩短首页中新闻提要的宽度,这是使用的CSS:

@media (min-height:700px) {  .element {    width: 584px;  }}

就是这样,伙计们。我喜欢撰写本文,并学到了很多东西。希望您觉得它有用,请传播它。

服务推荐

发布了0 篇原创文章 · 获赞 0 · 访问量 335

猜你喜欢

转载自blog.csdn.net/weixin_47143210/article/details/105675931
今日推荐