首页 《CSS揭秘》笔记3 — 视觉效果
文章
取消

《CSS揭秘》笔记3 — 视觉效果

此篇博客是学习《CSS 揭秘》一书的学习笔记。

1. 单侧投影

尝试实现单侧投影的代码如下: HTML

1
<div class="box-100 bg-red-4 bottom-shadow-4-1"></div>

CSS

1
2
3
.bottom-shadow-4-1 {
  box-shadow: 0 5px 4px black;
}

效果如下:

第三个值阴影模糊半径 4px 会导致模糊后的阴影显示在两侧,多出来的长度大约为 4px

我们可以使用第四个长度参数 —— 阴影扩散半径来消除两侧的阴影。当我们设置负的扩散半径时,阴影会根据指定的值缩小。
CSS

1
2
3
.bottom-shadow-4-1 {
  box-shadow: 0 5px 4px -4px black;
}

注:前后几个值分别为 x偏移量 | y偏移量 | 阴影模糊半径 | 阴影扩散半径 | 阴影颜色
最终效果如下:

邻边投影

HTML

1
<div class="box-100 bg-red-4 sides-shadow-4-2 margin-btm-14"></div>

CSS

1
2
3
.sides-shadow-4-2 {
  box-shadow: 4px 4px 6px -3px black;
}

注:

  1. 扩张半径(-3px)为模糊半径(6px)的相反值的一半。
  2. 偏移值要大于等于模糊半径(6px)的一半,这样投影才能被藏进另外两条边之内。

双侧投影

box-shadow 支持使用逗号分隔多个阴影效果。因此我们可以使用两个投影来实现双侧投影。

HTML

1
<div class="box-100 bg-red-4 opposite-sides-shadow-4-3 margin-btm-14"></div>

CSS

1
2
3
4
.opposite-sides-shadow-4-3 {
  box-shadow: 5px 0 5px -5px black,
             -5px 0 5px -5px black;
}

2. 不规则投影

在某些情况下, box-shadow 会忽略掉元素的一部分。如下面三种情况:

对话气泡
虚线边框
切角效果

给这几个元素添加 box-shadow 后效果如下:

对话气泡
虚线边框
切角效果

HTML

1
2
3
<div class="box-4-2 shadow-4-2 speech-bubble">对话气泡</div>
<div class="box-4-2 shadow-4-2 dotted-border">虚线边框</div>
<div class="box-4-2 shadow-4-2 cutout-corners">切角效果</div>

CSS

1
2
3
.shadow-4-2 {
  box-shadow: 2px 2px 6px rgba(0, 0, 0, .5);
}

我们可以使用 filter 属性,并使用 drop-shadow() 方法,它接受和 box-shadow 属性一样的参数,但不包括扩张半径和 inset 关键字。

注: IE 浏览器不支持该属性。

对话气泡
虚线边框
切角效果

CSS

1
2
3
.filter-4-2 {
  filter: drop-shadow(2px 2px 6px rgba(0, 0, 0, .5));
}

注: 任何非透明的部分都会被打上投影,例如虚线边框效果中的文字。

3. 毛玻璃效果

filter 属性有一个 blur() 方法可以设置高斯模糊。

HTML

1
2
3
4
5
6
7
8
9
10
11
12
<div class="frosted-glass">
  <div>
    <p>
      由于我们不能直接对元素本身进行模糊处理,但可以对伪元素进行模糊处理,
      然后将其定位到元素的下面,它的背景将会无缝匹配宿主元素的父元素的背景。
    </p>
    <p>
      在使用负的 z-index 来把一个子元素移动到他的父元素下层时,请务必小心;
      如果父元素的上级元素也有背景,则该子元素将出现在它们之后。
    </p>
  </div>
</div>

CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
* {
  margin: 0;
  padding: 0;
}
.frosted-glass {
  width: 100%;
  height: 500px;
  overflow: hidden; /* 防止子元素的 margin-top 影响此元素的定位 */
}
.frosted-glass div {
  position: relative;
  margin: 150px auto;
  width: 60%;
  padding: 20px;
  border-radius: 5px;
  overflow: hidden; /* 防止高斯模糊效果弱化元素边界 */
  background: hsla(0, 0%, 100%, .3);
  color: white;
  text-shadow: black 0.1em 0.1em 0.2em;
  z-index: 1;
}
.frosted-glass,
.frosted-glass div::after {
  background: url('/images/2019-06-01-css-secrets/book.jpg') 0 / cover fixed;
}
.frosted-glass div::after {
  content: "";
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  filter: blur(4px); /* 高斯模糊效果 */
  z-index: -1; /* 让伪元素位于内容之后 */
}

注:

由于为了使 div.frosted-glassdiv.frosted-glass div::after 两个元素的背景无缝匹配, 我们把 background-attachment 设为了 fixed:

1
2
3
4
.frosted-glass,
.frosted-glass div::after {
  background: url('/images/2019-06-01-css-secrets/book.jpg') 0 / cover fixed;
}

这会让背景不会随着元素的内容滚动。其中 / 前面的 0background-position ,当只设置了一个值时,Y 方向的值为 center

为了不让图片在滚动的时候,出现背景和文字相对移动的情况,上图使用 <iframe> 标签内嵌了一个 HTML 页面,否则就会出现如下情况。

由于我们不能直接对元素本身进行模糊处理,但可以对伪元素进行模糊处理, 然后将其定位到元素的下面,它的背景将会无缝匹配宿主元素的父元素的背景。

在使用负的 z-index 来把一个子元素移动到他的父元素下层时,请务必小心; 如果父元素的上级元素也有背景,则该子元素将出现在它们之后。

4. 折角效果

45°折角效果

我们可以利用 3.4 切角效果 一节中的渐变方法去实现此效果。

先实现缺角效果:

缺角效果

CSS

1
2
3
.folded-corner-4-4.step-1 {
  background: linear-gradient(-135deg, transparent 1.42em, #ff7873 0);
}

再实现折角效果:

折角效果

CSS

1
2
3
.folded-corner-4-4.step-2 {
  background: linear-gradient(45deg, rgba(0, 0, 0, .4) 1.42em, transparent 0) top right / 2em 2em no-repeat;
}

最后重叠:

最终效果

CSS

1
2
3
4
.folded-corner-4-4.step-3 {
  background: linear-gradient(45deg, rgba(0, 0, 0, .4) 1.42em, transparent 0) top right / 2em 2em no-repeat,
              linear-gradient(-135deg, transparent 1.42em, #ff7873 0);
}

注: 折角效果要放在切角效果后面。

其他角度折角效果

我们可以改变角度和折角背景的宽和高,就能形成如下 30° 折角效果:

30°折角

CSS

1
2
3
4
5
.folded-corner-4-4.step-4 {
  background: linear-gradient(30deg, rgba(0, 0, 0, .4) 1.42em, transparent 0) 
                  top right / 2.84em 1.64em no-repeat,
              linear-gradient(-150deg, transparent 1.42em, #ff7873 0);
}

我们发现折角效果并不真实,折角和缺角应该是沿着斜边对称的。

由于背景无法旋转,我们可以旋转伪元素

30°折角(伪元素)
30°折角(旋转伪元素)
30°折角(最终效果)

HTML

1
2
3
<div class="folded-corner-4-4 margin-btm-14 step-5">30°折角(伪元素)</div>
<div class="folded-corner-4-4 margin-btm-14 step-5 step-6">30°折角(旋转伪元素)</div>
<div class="folded-corner-4-4 margin-btm-14 step-5 step-6 step-7">30°折角(最终效果)</div>

CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
.folded-corner-4-4.step-5 {
  display: inline-block;
  position: relative;
  margin-right: 14px;
  background: linear-gradient(-150deg, transparent 1.42em, #ff7873 0);
  border: none;
}
.folded-corner-4-4.step-5::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  width: 2.84em;
  height: 1.64em;
  background: linear-gradient(-30deg, rgba(0, 0, 0, .4) 50%, transparent 0);
}
.folded-corner-4-4.step-6::before {
  transform: rotate(60deg);
}
.folded-corner-4-4.step-7 {
  border-radius: .4em;
}
.folded-corner-4-4.step-7::before {
  background: linear-gradient(-30deg, 
              rgba(0, 0, 0, .4) 0, 
              rgba(0, 0, 0, .2) 50%, 
              transparent 0);
  border-bottom-right-radius: inherit;
  box-shadow: .2em .2em .3em -.1em rgba(0, 0, 0, .15);
}

重点:

  1. 切角效果放在 div 元素上,折角效果放在 div::before 伪元素上;
  2. 伪元素的宽高为之前折角效果背景的宽高;
  3. 伪元素的背景的线性角度由 30deg 变为 -30deg(左图);
  4. 最后把伪元素旋转 60deg (右图)。
本文由作者按照 CC BY 4.0 进行授权