【译】不止是 box-shadow,用 css 能表现的各类影子,以及各类陷阱!

正在从事网页设计者或者从事前端的小伙伴们,必定会有想要加阴影的时候吧。
那么阴影会是什么样的表现,以及须要那些参数,你了解的多少呢?
复制代码

通常要加阴影,就会想到要用 css 的 box-shadow 吧,实际上还有好几种表现方式。暂且不说网页,在逐年变化的设计潮流里,怎么处理阴影也是很重要的一个课题。css

就好比说早些时间流行的长投影,以及今年开始流行的 Neumorphism(拟态)什么的。其独特的影子表现手法,也是各显千秋。html

▼ 用 css 制做的 长投影,和 拟态 的例子:前端

在这篇文章,将会介绍各类影子的技术手段,以及各个参数。git

box-shadow 基础

用 css 添加阴影,最最最最最容易想到的就是 box-shadow 了。
复制代码

复习 box-shadow 参数

首先看一下 box-shadow 的参数。 github

就算最基本的 box-shadow,也是能够实现的各类效果。 chrome

/* 1. 基础的 box-shadow */
.basic1 {
  box-shadow: 0 10px 25px 0 rgba(0, 0, 0, .5);
}
/* 2. 使用 inset 添加内阴影。圆也没问题。 */
.basic2 {
  box-shadow: inset 0 10px 25px 0 rgba(0, 0, 0, .5);
}
/* 3. 能够指定任意的颜色以及透明度 */
.basic3 {
  box-shadow: 0 10px 25px 0 rgba(60, 194, 235, 0.5);
}
/* 4.经过偏移量,写出像 border 同样的效果 */
.basic4 {
  box-shadow: 15px 15px 0px 0 rgb(60, 194, 235);
}
复制代码

多个阴影重叠

咱们能够写任意个阴影,而且重叠,来看看下面的例子吧!windows

/* 1. 经过 6 层阴影重叠,实现更加真实的投影 */
.layer1 {
  box-shadow:
    0 1.9px 2.5px rgba(0, 0, 0, 0.057),
    0 5px 6.1px rgba(0, 0, 0, 0.076),
    0 10.1px 11.4px rgba(0, 0, 0, 0.086),
    0 19.2px 19.8px rgba(0, 0, 0, 0.092),
    0 38.4px 34.8px rgba(0, 0, 0, 0.1),
    0 101px 74px rgba(0, 0, 0, 0.13);
}
/* 2. 影子朝不一样的方向,指定不一样颜色 */
.layer2 {
  box-shadow:
    -10px 10px 25px rgba(230, 180, 15, 0.9),
    10px -10px 25px rgba(8, 131, 161, 0.9)
}
/* 3. 利用多层重叠,让阴影看起来像不少层纸 */
.layer3 {
  box-shadow:
    0 20px 0 -10px rgb(198, 224, 231),
    0 40px 0 -20px rgb(105, 171, 209),
    0 60px 0 -30px rgb(27, 115, 165)
}
复制代码

经过多层的阴影重叠,是一种常见的用法。就好比在 google 浏览器的弹窗,随处可见。浏览器

非 box-shadow,伪元素模拟的阴影

box-shadow 虽然很简单,但也有实现不了的场景。 下图的左边,是蓝色的 box-shadow 实现的阴影。下图右边是伪元素实现的阴影,右边的是否是看起来更加真实呢?svg

demo 示例🔗性能

解析伪元素模拟阴影

box-shadow 只是给加上指定颜色的 blur(模糊)效果,影子的颜色跟背景组合在一块儿的话,看起来不太天然。 若是要实现更加真实的阴影,咱们能够利用 css 的 filter 跟 mix-blend-mode 配合。(不要跟我谈 ie,那是什么,能够吃吗!)

.box::after {
  /* 经过伪元素设置相同的大小,而且在背面表示 */
  content: '';
  display: block;
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;

  /* ①添加颜色 */
  background-color: rgb(42, 159, 226);
  /* ②添加模糊*/
  filter: blur(15px);
  /* ③调整位置和大小 */
  transform: translateY(10px) scale(1.05);
  /* ④添加混合效果 */
  mix-blend-mode: multiply;
}
复制代码

跟只有一行的 box-shadow 比起来确实麻烦了很多,可是伪元素能够调整大小,加上任意的 filter,能够实现更加自由的组合。 咱们来看几个例子吧!

给渐变色或者照片加上阴影

跟 box-shadow 不一样,伪元素能够投影渐变图像以及任意的图片。这样模糊的阴影,画面的印象更深!

改变混合效果

出了普通的投影以外,咱们还能够试着改变不一样的混合效果。

上面的例子,是用 color-dodge 表象出来发光的效果,另外能够利用 color-burn、 hard-light 等等表象出各式各样的效果。

另外一种阴影 dorp-shadow

还有一个咱们不要忽视的是 drop-shadow。box-shadow 只可以给元素的四个边角加上投影,但 drop-show 能够跟实际内容结合来产生投影。实际内容是指位图、svg 图、文本、子元素等等,基本上全部的东西均可以。若是只想给看到的东西、直接给其加上阴影的话,那就使用 drop-shadow 吧!

drop-shadow 跟 box-shadow 写法不一样之处

drop-shadow 是属于 css 的 filter 的一种。虽然参数少了几个,但跟 box-shadow 基本一致。

有几个注意点:

  1. 就算跟 box-shadow 设定成一样的值,drop-shadow 看起来会更加模糊。
  2. drop-shadow 不可使用 inset。
  3. drop-shadow 算上 x、y 的偏移量就只有 4 个参数,设定错了会没效果。
  4. drop-shadow 不支持 ie。虽然能够经过(filter: progid:DXImageTransform.Microsoft.DropShadow),这里不作介绍。

下图是比较一样值,box-shadow 跟 drop-shadow 的比较,若是最求设计稿跟画面高度一致的话,能够注意一下。

drop-shadow 能够解决阴影重叠

接下来这个例子是 css animation 制做的 loading 效果。用旋转着的 8 个小圆圈来模仿 windows 加载动画的效果。

两个示例都是给加的左侧阴影、box-shadow 的表现挺差强人意的:

  • 由于给每一个元素加上了阴影,因此看起来不像是一个总体。
  • 若是加上了动画的话,会更加的混乱。

左侧是给每一个子元素加上 box-shadow 的,而右边是给子元素的父元素加上的 drop-shadow,这是没法避免的,这里稍微提醒一下。

总而言之,drop-shadow 支持投影的重叠。

阴影的内幕 - 陷阱与对策

box-shadow 跟 drop-shadow,背后是浏览器复杂的渲染运算,所以会有不少坑,这里,咱们再去试着跟 animation 组合,看看会有哪些坑,而且会介绍一下应对策略。

陷阱1:卡顿(Safari)

在元素 hover 状态下加上 transition 的投影动画,chrome、safari 表现不一样,safari 会稍微有点卡顿。

这个现象的产生缘由,主要是由于变动了 box-shadow 的模糊半径。虽然不可以达到彻底一致的效果,可是若是注重流畅的效果的话,能够替换成改变颜色透明度。

/* 1. 改变模糊半径 */
.box1{
  transition: box-shadow 2s ease-out, transform 2s ease-out;
}
.box1:hover {
  box-shadow: 0 15px 10px 5px rgb(0, 0, 0);
  transform: translateY(-10px);
}

/* 2. 只改变透明度 */
.box2{
  transition: box-shadow 2s ease-out, transform 2s ease-out;
  box-shadow: 0 15px 10px 5px rgba(0, 0, 0, 0);
}
.box2:hover {
  box-shadow: 0 15px 10px 5px rgba(0, 0, 0, 1);
  transform: translateY(-10px);
}
复制代码

陷阱2:hover 的阴影会被溢出隐藏(Safari)

hover 的状态下,drop-shadow 也会出问题。 溢出会被裁切掉。

在 safari 改变 drop-shadow 的话,内部会从新渲染产生了这个问题。虽然有点麻烦,可是若是实在须要的话,咱们须要给元素加上足够空间的 padding。

.ok {
  display: inline-block;
  font-size: 0;
  /* 添加足够空间的padding */
  padding: 100px; 
  filter: drop-shadow(0 0px 3px rgba(0, 0, 0, .9));
}
.ok:hover {
  filter: drop-shadow(0 10px 60px rgba(0, 0, 0, .9));
}
复制代码

陷阱3: 动画过程当中,阴影没法显示(Safari)

这个也是在 safari 的现象。

用三个 div 配合 transition 动画作了一个菜单,若是给 icon 全体都加上 dorp-shadow 的话,在 safari 里面阴影会消失。

如下是这个现象发生的条件:

  • 多个子元素加上了 transition 跟 transform。
  • 两个以上的子元素使用了 drop-shadow。

多个阴影重叠的手法在设计中会常常出现,若是直接复制的话,说不定就达成了条件。

陷阱4: 添加了太多阴影动画的话,浏览器会难消化(Chrome、Firefox)

最后一个是在 chrome、firefox 出现的陷阱。咱们试着给 100 个 div 加上阴影、配合 css 的 animation。进行下面 3 种实验

  1. 给每一个子元素加上 box-shadow。
  2. 给每一个子元素加上 drop-shadow。
  3. 给父元素加上 drop-shadow。

可能机器个体性能不一样,写这片文章的时候使用的平台是 iMac(iMac 5K, 27-inch, 2019)

demo 示例🔗

浏览器 每一个子元素加上 box-shadow 给每一个子元素加上 drop-shadow 给父元素加上 drop-shadow
Chrome(80) 超慢
Safari(13.1) 通常
Firefox(74)

每一个浏览器的倾向都不一样。特别是 chrome 的 drop-shadow。若是给元素增长到 200 个的话,只剩 10 fps 了。

safari从一开始就用 gpu 处理渲染了,而 chrome 的话会让 cpu 爆炸。若是是这样的场景的话,那么各个浏览器得好好确认了。不过,如今应该很难见到 box-shadow 加上 animation 这种场景了吧。

总结

这片文章介绍了 box-shadow、drop-shadow、已经伪元素配合 css filter 模拟的阴影的各类手段。特别是在使用动画的时候,会有各类不同的效果,须要注意一小下,只要遵照这些隐藏规定的话,css 表现阴影仍是挺强的。期待您掌握 css 的阴影技术,下次在实际应用场景上发挥地更加出色。

译者记录

在了解这片文章以前,我仍是只知道 box-shadow 能够产生阴影,彻底没有注意到 drop-shadow 也能够作投影。元素模拟却是有知道一点,可是表现的这么出色,却是不多见。

偶然间发现这片文章,介绍了阴影的各类手法,每一个点都很细致的介绍到了,很是的不错,特地花了点时间翻译了一下,分享给你们,但愿可以派的上用场,让你们对 css 的阴影可以有更加深入的理解。

原文地址:ics.media/entry/20040…

做者:松本 ゆき

翻译:view

相关文章
相关标签/搜索