likes
comments
collection
share

阴影的几种实现方式你都会了吗说到前端阴影,大家肯定会第一时间想到box-shadow,一个CSS轻松搞定,但是本文要说的

作者站长头像
站长
· 阅读数 80

说到前端阴影,大家肯定会第一时间想到box-shadow,一个CSS轻松搞定,但是本文要说的不止box-shadow,主要介绍5种实现方式之间的特性和差异。

现有如下HTML结构

<div class="wrapper">
  <div class="block"></div>
  <div class="block"></div>
  <div class="block"></div>
  <div class="block">未来可期</div>
  <div class="block"></div>
  <div class="block">
    <div class="image-move">未来可期</div>
    <div class="image-move shadow">未来可期</div>
  </div>
</div>

<style>
* {
  box-sizing: border-box;
}

body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: auto;
}

.wrapper {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}

.block {
  flex: 0 1 auto;
  position: relative;
  width: 150px;
  height: 150px;
  margin: 50px;
}
</style>

1、box-shadow

众所周知的CSS属性,但是作为对比,还是简单介绍一下

/* x 偏移量 | y 偏移量 | 阴影模糊半径 | 阴影扩散半径 | 阴影颜色 | 阴影位置 */
box-shadow: 10px 10px 20px 5px rgba(0, 0, 0, 0.5) inset;
/* 多个阴影用英文逗号隔开 */
box-shadow: 10px 10px 20px 5px rgba(0, 0, 0, 0.5) inset, 0px 0px 30px red;

box-shadow共有6个可设置属性值,除了x偏移量、y偏移量是必填的,其他都是选填。

1)以下CSS,会将第1个.block元素渲染为

.block:nth-child(1) {
  box-shadow: inset 16px 16px 20px red;
}

阴影的几种实现方式你都会了吗说到前端阴影,大家肯定会第一时间想到box-shadow,一个CSS轻松搞定,但是本文要说的

2)以下CSS,会将第2个.block元素渲染为

.block:nth-child(2) {
  box-shadow: 16px 16px 20px red;
}
.block:nth-child(2)::after {
  content: '';
  display: block;
  width: 20px;
  height: 220px;
  margin: auto;
  background: yellow;
}

阴影的几种实现方式你都会了吗说到前端阴影,大家肯定会第一时间想到box-shadow,一个CSS轻松搞定,但是本文要说的

以上效果,::after伪元素虽然在.block元素内,但是不会产生阴影效果,因为box-shadow只作用于目标元素,不会对子元素产生任何影响。

2、filter: drop-shadow

drop-shadow的属性值跟box-shadow大体上一样,不同的地方在于drop-shadow没有inset和阴影扩散半径,所以drop-shadow的取值如下

/* x 偏移量 | y 偏移量 | 阴影模糊半径 | 阴影颜色 */
filter: drop-shadow(10px 10px 20px rgba(0, 0, 0, 0.5));
/* 多个阴影用空格隔开 */
filter: drop-shadow(10px 10px 20px rgba(0, 0, 0, 0.5)) drop-shadow(12px 12px 30px red);

以下CSS,会将第3个.block元素渲染为

.block:nth-child(3) {
  background: blue; /* 没有非透明值则drop-shadow不会生效 */
  filter: drop-shadow(16px 16px 20px red);
}
.block:nth-child(3)::after {
  content: '';
  display: block;
  width: 20px;
  height: 220px;
  margin: auto;
  background: yellow;
}

阴影的几种实现方式你都会了吗说到前端阴影,大家肯定会第一时间想到box-shadow,一个CSS轻松搞定,但是本文要说的

以上效果,虽然没有给::after伪元素声明任何阴影,但是仍然会有阴影效果,可以将drop-shadow理解成投影,drop-shadow作用的元素及其子孙元素,只要产生新的边界的,一定会有投影,比如上面黄色的模块,在蓝色模块内交集的地方并没有产生阴影,只在蓝色模块之外产生了阴影,这也是drop-shadow和box-shadow不同的地方。并且对比前面的box-shadow,一样的阴影属性值(16px 16px 20px red),drop-shadow的阴影效果更淡、更扩散些。

假如我们把黄色::after元素设置marign-left: 200px移出蓝色模块之外,则会产生如下效果

阴影的几种实现方式你都会了吗说到前端阴影,大家肯定会第一时间想到box-shadow,一个CSS轻松搞定,但是本文要说的

综合上面几点,drop-shadow跟box-shadow不同的点在于

  1. drop-shadow没有阴影扩散半径和inset设置,box-shadow有;

  2. drop-shadow作用的元素,只要该元素及其子孙元素产生新的边界,就会产生投影阴影效果,而box-shadow只作用于元素本身;

  3. 同样的属性值(16px 16px 20px red),drop-shadow产生的阴影效果更淡、渐变效果更好,而box-shadow的阴影颜色更重。

3、text-shadow文字阴影

text-shadow的属性值跟box-shadow大体上一样(跟drop-shadow完全一样),不同的地方在于text-shadow没有inset和阴影扩散半径,text-shadow的取值如下:

/* x 偏移量 | y 偏移量 | 阴影模糊半径 | 阴影颜色 */
text-shadow: 10px 10px 10px rgba(0, 0, 0, 0.5);
/* 多个阴影用英文逗号隔开 */
text-shadow: 10px 10px 10px rgba(0, 0, 0, 0.5), 0px 0px 10px red;

以下代码,会将第4个.block元素渲染为

.block:nth-child(4) {
  font-size: 54px;
  font-weight: bold;
  text-align: center;
  border: 1px solid #000;
  text-shadow: 10px 10px 8px red;
}

阴影的几种实现方式你都会了吗说到前端阴影,大家肯定会第一时间想到box-shadow,一个CSS轻松搞定,但是本文要说的

4、filter滤镜 + 伪元素

已知filter: blur(5px)CSS滤镜能让元素产生高斯模糊效果,如果我们加一个伪元素,给伪元素加上这个滤镜、加上适当的位移,是不是也可以模拟box-shadow的效果呢,答案是肯定的。当然,这种方式也是没法实现阴影扩散半径和inset的效果,下面我们来看个例子。

以下代码,会将第5个.block元素渲染为

.block:nth-child(5) {
  position: relative;
  background: url("static/image/butterfly.jpeg") no-repeat center center;
  background-size: cover;
  &::after {
    content: "";
    position: absolute;
    z-index: -1;
    top: 16px;
    left: 16px;
    width: 100%;
    height: 100%;
    background: inherit;
    background-size: cover;
    filter: blur(20px) opacity(0.8);
  }
}

阴影的几种实现方式你都会了吗说到前端阴影,大家肯定会第一时间想到box-shadow,一个CSS轻松搞定,但是本文要说的

图片原图如下:(图片来自500px,非商业用途,如有侵权删)

阴影的几种实现方式你都会了吗说到前端阴影,大家肯定会第一时间想到box-shadow,一个CSS轻松搞定,但是本文要说的

保持上面CSS不变,我们换一张图片,会产生不同颜色的阴影效果,说明这种方式的阴影是会跟随元素颜色变化的。

阴影的几种实现方式你都会了吗说到前端阴影,大家肯定会第一时间想到box-shadow,一个CSS轻松搞定,但是本文要说的

如上效果可以看到,filter blur + 伪元素模拟的阴影效果,更加淡雅,并且会随着元素背景内容颜色变化,由于是filter+伪元素实现的,所以xy轴的偏移靠top、left属性来设置,模糊半径及效果靠filter: blur(半径) opacity(透明度)来实现。

5、filter滤镜 + background-clip裁剪 = 文字阴影

上面第4点演示了filter产生跟随元素背景变化的阴影,不经联想到,文字阴影有没有办法达到这种效果呢,不妨来试试。

如下代码,会将第6个.block元素渲染为

.image-move {
  position: relative;
  font-size: 54px;
  font-weight: bold;
  text-align: center;
  border: 1px solid red;
  overflow: hidden;
}
.shadow {
  position: absolute;
  left: 10px;
  top: 10px;
  width: 100%;
  background: url("static/image/butterfly.jpeg");
  background-size: 100% 100%;
  background-position: 0% 0%;
  -webkit-background-clip: text;
  color: transparent;
  filter: blur(3px) opacity(0.5);
}

阴影的几种实现方式你都会了吗说到前端阴影,大家肯定会第一时间想到box-shadow,一个CSS轻松搞定,但是本文要说的

文字阴影效果产生了,并且阴影的文字还是以图片为底裁剪出来的,效果还不错。

接着我们换种方式,给两个.image-move都加上backgroup和backgroup-clip看看效果:

.image-move {
  position: relative;
  font-size: 54px;
  font-weight: bold;
  text-align: center;
  border: 1px solid red;
  overflow: hidden;
  background: url("static/image/butterfly.jpeg");
  background-size: 100% 100%;
  background-position: 0% 0%;
  -webkit-background-clip: text;
  color: transparent;
  /* color: rgba(255, 0, 0, 0.2); */
}
.shadow {
  position: absolute;
  left: 10px;
  top: 10px;
  width: 100%;
  filter: blur(3px) opacity(0.5);
}

阴影的几种实现方式你都会了吗说到前端阴影,大家肯定会第一时间想到box-shadow,一个CSS轻松搞定,但是本文要说的

效果更加惊艳,试想一下,将背景换成渐变图案或者其他图片,是不是有更多不同效果。

以上用到了好几个CSS特性,但产生文字背景裁剪效果的必要前提是:

  1. 声明了background-image或者background-color

  2. 声明了-webkit-background-clip: text

  3. 字体颜色要带有透明度,比如color: transparentcolor: rgba(255, 0, 0, 0.2),并且不同颜色不同透明度的效果也不一样

总结

虽然都是普通常见的CSS属性,但组合到一起就可以产生不同的效果,所以最重要的是要理解每个CSS的特性,善用CSS,才能激发更多创意。

本文介绍了5种实现阴影的方式,每种方式效果、兼容性不完全一致,需根据实际情况选择。

大千世界无奇不有,如有其他实现方式也非常欢迎评论区讨论。

转载自:https://juejin.cn/post/7410668201779396627
评论
请登录