正在从事网页设计者或者从事前端的小伙伴们,一定会有想要加阴影的时候吧。
那么阴影会是什么样的表现,以及需要那些参数,你了解的多少呢?
复制代码
一般要加阴影,就会想到要用 css 的 box-shadow 吧,实际上还有好几种表现方式。暂且不说网页,在逐年变化的设计潮流里,怎么处理阴影也是很重要的一个课题。
就比如说早些时间流行的长投影,以及今年开始流行的 Neumorphism(拟态)什么的。其独特的影子表现手法,也是各显千秋。
▼ 用 css 制作的 长投影
,和 拟态
的例子:
在这篇文章,将会介绍各种影子的技术手段,以及各个参数。
box-shadow 基础
用 css 添加阴影,最最最最最容易想到的就是 box-shadow 了。
复制代码
复习 box-shadow 参数
首先看一下 box-shadow 的参数。
就算最基本的 box-shadow,也是可以实现的各种效果。
/* 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);
}
复制代码
多个阴影重叠
我们可以写任意个阴影,并且重叠,来看看下面的例子吧!
/* 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 实现的阴影。下图右边是伪元素实现的阴影,右边的是不是看起来更加真实呢?
解析伪元素模拟阴影
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 基本一致。
有几个注意点:
- 就算跟 box-shadow 设定成同样的值,drop-shadow 看起来会更加模糊。
- drop-shadow 不可以使用 inset。
- drop-shadow 算上 x、y 的偏移量就只有 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 种实验
- 给每个子元素加上 box-shadow。
- 给每个子元素加上 drop-shadow。
- 给父元素加上 drop-shadow。
可能机器个体性能不同,写这片文章的时候使用的平台是 iMac(iMac 5K, 27-inch, 2019)
浏览器 | 每个子元素加上 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 的阴影能够有更加深刻的理解。
作者:松本 ゆき
翻译:view
来源:oschina
链接:https://my.oschina.net/u/4356138/blog/3227706