悬停效果之 transform

Grow Shadow

1
2
3
4
5
6
7
8
9
10
11
12
13
<h3 class="hover-1">Hover Me</h3>

<style>
.hover-1 {
background-color: #1095c1;
color: #ffffff;
transition: .4s;
}
.hover-1:hover {
transform: scale(1.1);
box-shadow: 0 10px 10px -10px rgba(0, 0, 0, .5);
}
</style>

Float Shadow

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
<h3 class="hover-2">Hover Me</h3>

<style>
.hover-2 {
position: relative;
line-height: 1.2em;
background-color: #1095c1;
color: #ffffff;
transition: .4s;
}
.hover-2:after {
content: "";
position: absolute;
top: 100%;
left: 5%;
height: 20px;
width: 90%;
z-index: -1;
opacity: 0;
background: radial-gradient(farthest-side, rgba(0, 0, 0, .35), #ffffff) no-repeat;
transition: .4s;
}
.hover-2:hover {
transform: translateY(-10px);
}
.hover-2:hover:after {
opacity: 1;
transform: translateY(10px);
}
</style>

Bubble Right

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
<h3 class="hover-3">Hover Me</h3>

<style>
.hover-3 {
position: relative;
line-height: 1.2em;
background-color: #1095c1;
color: #ffffff;
}
.hover-3:before {
content: "";
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
border: solid;
border-width: 12px 0 12px 15px;
border-color: transparent transparent transparent #1095c1;
z-index: -1;
transition: .4s;
}
.hover-3:hover:before {
transform: translate(100%, -50%);
}
</style>

3D 旋转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<h3 class="hover-4">Hover Me</h3>

<style>
.hover-4 {
padding: 8px 8px 8px 22px;
background: linear-gradient(rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.4)) left/14px 100% no-repeat;
polygon(14px 3px, 14px 0, 100% 0, 100% 100%, 14px 100%, 14px calc(100% - 3px));
transition: 0.4s, color 0.4s 0.4s, background-color 0.4s 0.4s;
}
.hover-4:hover {
background-color: #000;
color: #fff;
clip-path: polygon(0px 3px, 14px 0, 100% 0, 100% 100%, 14px 100%, 0 calc(100% - 3px));
transform: perspective(1000px) rotateY(40deg);
transition: 0.4s 0.4s, color 0.4s, background-color 0.4s;
}
</style>

通过 padding 在左侧留出 14px *100% 的空间,向其中填充背景图,用作翻转后的阴影部分。

初始时, clip-path 的范围包括除了最左边 14px * 100% 的所有部分,即显示没有背景的部分。当 hover 时,改变 clip-path,将左侧背景图也包含进去,但是左上和左下两个点的纵坐标少取了一些,以呈现出立体的感觉。

perspective 属性设置从何处查看一个元素的角度,单位为 px,值越小角度越大。

注意:hover 前后的 clip-path 形状的坐标点数量应保持一致,只通过改变坐标点的值来改变形状,因为这样可以有更好的过渡效果。

下面我们来看一个例子:

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
<div class="box">
<img src="https://i.picsum.photos/id/1011/400/250.jpg?hmac=E9wN15u_CpjA8P_xTXExwDTjYdKQ0olRCmuV3x893fAhttps://i.picsum.photos/id/1011/400/250.jpg?hmac=E9wN15u_CpjA8P_xTXExwDTjYdKQ0olRCmuV3x893fA" alt="">
</div>

<style>
img {
padding: 20px 20px 0 20px;
outline: 20px solid rgba(0, 0, 0, .4);
outline-offset: -20px;
clip-path: polygon(
20px 20px,
calc(100% - 20px) 20px,
calc(100% - 20px) calc(100% - 20px),
calc(100% - 20px - 10px) calc(100% - 20px),
calc(20px + 10px) calc(100% - 20px),
20px calc(100% - 20px)
);
transition: 1s;
}
img:hover {
transform: perspective(1000px) rotateX(40deg);
clip-path: polygon(
20px 20px,
calc(100% - 20px) 20px,
calc(100% - 20px) calc(100% - 20px),
calc(100% - 20px - 10px) 100%,
calc(20px + 10px) 100%,
20px calc(100% - 20px)
);
}
</style>

由图可知,旋转后的阴影部分也是图片的一部分,那怎么实现这种效果呢?

这里用到了 outline 属性。它与 border 的效果相似。不同的是:

  • outline 不占用布局空间,它不是盒子模型的一部分;

  • 它创建的轮廓四条边都是一样的,不能单独为某一条边设置样式;

  • 它创建的轮廓可以向内扩展(outline-offset 为负),而 border 只能向外。

这里主要使用到了它的第三条特性。

(1)首先,为了在图片底部设置高 20px 的阴影效果,我们设置

1
2
3
outline: 20px solid rgba(0, 0, 0, .4);
outline-offset: -20px;
padding: 20px 20px 0 20px;

效果如下:

(2)通过 clip-path 进行区域裁剪。初始时,裁剪没有阴影的部分,hover 时将底部的阴影也裁剪出来,为了有立体感,最下面两个坐标点向中间靠拢 10px。效果如下:

(3)通过旋转即可呈现出最后的效果。