从左进入,右边离开
我们将一个 hover 动画分解为 3 个部分:
- hover 进入状态
- hover 停留状态
- hover 离开状态
div {
xxxx...
}
div:hover {
xxxx...
}
对于一个 hover transition 动画,它应该是从:
- 正常状态 -> hover状态 -> 正常状态 (三个步骤,两种状态)
所以,必须要有一种方法,能够使得 hover 动画的进入与离开产生两种不一样的效果,实现:
- 状态1 -> hover状态 -> 状态2 (三个步骤,三种状态)
实现控制动画方向的关键点
所以,这里的关键点就在于(划重点):
使得 hover 动画的进入与离开产生两种不一样的效果 。
接下来,也就是本文的关键所在,使用 transform: scale()
以及 transform-origin
实现这个效果。
transform: scale()
实现线条运动
transform: scale 大家应该都很熟悉了,通俗来说是用于缩放,用官方的话说,就是:
CSS 函数 scale() 用于修改元素的大小。可以通过向量形式定义的缩放值来放大或缩小元素,同时可以在不同的方向设置不同的缩放值。
这里我们使用 transform: scaleX(0)
与 transform: scaleX(1)
来改变线条的显示与隐藏,它的 CSS 代码简单来看,可能是这样:
div {
position
:
absolute
;
width
:
200px
;
height
:
60px
;
}
div::before {
content
:
""
;
position
:
absolute
;
left
:
0
;
bottom
:
0
;
width
:
200px
;
height
:
2px
;
background
: deeppink;
transition: transform .
5
s;
transform: scaleX(
0
);
}
div:hover::before {
transform: scaleX(
1
);
}
transform: scale()
来实现线条的动画?因为它可以配合 transform-origin
实现动画的不同运动方向:
transform-origin
实现线条运动方向
transform-origin
让我们可以更改一个元素变形(transform)的原点,transform-origin
属性可以使用一个,两个或三个值来指定,其中每个值都表示一个偏移量。 没有明确定义的偏移将重置为其对应的初始值。
本效果最最最重要的地方就在于这里,我们使用 transform-origin
去改变 transform: scale()
的原点实现线条运动的方向。
- 我们给线条设置一个默认的
transform-origin
记为状态1 - hover 的时候,设置另外一个不同的
transform-origin
, 记为状态2
所以,当然我们 hover 的时候,会读取状态2的transform-origin
,从该原点开始放大至 scaleX(1)
,hover 离开的时候,会读取状态1的transform-origin
,从scaleX(1)
状态缩小至该原点。
<div>Hover Me</div>
body {
padding: 50px;
}
div {
position: absolute;
width: 200px;
height: 60px;
line-height: 60px;
font-size: 32px;
cursor: pointer;
color: #333;
text-align: center;
transition: color .5s;
margin: 20px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
div::before {
content: "";
position: absolute;
left: 0%;
bottom: 0;
width: 200px;
transform: scaleX(0);
height: 2px;
background: deeppink;
z-index: -1;
transition: transform .5s;
transform-origin: 100% 0;
}
div:hover::before {
transform: scaleX(1);
transform-origin: 0 0;
}
注意,这里使用了 transform-origin
去改变 transform: scale()
的原点实现线条运动的方向,而没有借助诸如 position
位移,transform: translate()
,或者 margin 等位置属性去改变线条所在的位置。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style>
body {
padding: 30px;
}
div {
position: relative;
width: 200px;
height: 60px;
line-height: 60px;
font-size: 32px;
cursor: pointer;
color: #333;
text-align: center;
transition: color .5s;
margin: 10px;
}
div::before {
content: "";
position: absolute;
left: 0;
width: 200px;
height: 60px;
background: deeppink;
z-index: -1;
-webkit-transform: scale3d(0, 1, 1);
transform: scale3d(0, 1, 1);
-webkit-transform-origin: 100% 50%;
transform-origin: 100% 50%;
transition: -webkit-transform .5s;
transition: transform .5s;
transition: transform .5s, -webkit-transform .5s;
}
div:hover {
color: #fff;
}
div:hover::before {
-webkit-transform: scale3d(1, 1, 1);
transform: scale3d(1, 1, 1);
-webkit-transform-origin: 0% 50%;
transform-origin: 0% 50%;
transition-timing-function: ease-in;
}
.two::before {
-webkit-transform: scale3d(0, 0, 1);
transform: scale3d(0, 0, 1);
-webkit-transform-origin: 100% 100%;
transform-origin: 100% 100%;
}
.two:hover {
color: #fff;
}
.two:hover::before {
-webkit-transform: scale3d(1, 1, 1);
transform: scale3d(1, 1, 1);
-webkit-transform-origin: 0% 0%;
transform-origin: 0% 0%;
}
.three::before {
-webkit-transform: scale3d(0, 0, 1);
transform: scale3d(0, 0, 1);
-webkit-transform-origin: 50% 100%;
transform-origin: 50% 100%;
}
.three:hover {
color: #fff;
}
.three:hover::before {
-webkit-transform: scale3d(1, 1, 1);
transform: scale3d(1, 1, 1);
-webkit-transform-origin: 50% 0%;
transform-origin: 50% 0%;
}
</style>
</head>
<body>
<div>Hover Me</div>
<div class="two">Hover Me</div>
<div class="three">Hover Me</div>
</body>
</html>