CSS3 动画专题
0x01 过渡 transition
- 过渡(transition)是应用于特定元素的 CSS 属性,在指定时间内平滑过渡到目标样式
(1)必要属性
- 使用
transition-property
指定需要过渡的 CSS 属性- 可以列入一个或多个 CSS 属性
- 也可以使用
all
值,表示所有变化的 CSS 属性都需要过渡 - 仅可以用于过渡的值是可以用数字表示的属性,浏览器会计算并插入中间值实现过渡
- 使用
transition-duration
指定过渡需要的持续时间
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
button {
width: 200px;
height: 100px;
font-size: 20px;
border: none;
color: white;
background-color: red;
cursor: pointer;
transition-property: background-color;
transition-duration: 1s;
}
button:hover {
background-color: purple;
}
</style>
</head>
<body>
<button>Button</button>
</body>
</html>
(2)其他属性
- 使用
transition-timing-function
指定过渡的时序函数(指过渡的变化方式)ease
:慢入、快变、慢出(默认)linear
:匀速ease-in
:缓慢开始,结束前加快ease-out
:快速开始,结束前减慢ease-in-out
:与ease
类似
- 使用
transition-delay
指定过渡的延迟时间
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
button {
width: 200px;
height: 100px;
font-size: 20px;
border: none;
color: white;
background-color: red;
cursor: pointer;
transition-property: background-color;
transition-duration: 1s;
transition-timing-function: ease-in;
transition-delay: 0.5s;
}
button:hover {
background-color: purple;
}
</style>
</head>
<body>
<button>Button</button>
</body>
</html>
(3)缩写属性
transition: property duration timing-function delay[, property duration timing-function delay];
0x02 变换 transform
- 变换(transform)是指改变元素的尺寸、形状以及位置
- 变换提供了 4 种函数来控制元素的显示方式:
scale
、translate
、rotate
、skew
transform-origin
:设定变换原点- 默认取值包括
top
、left
、right
、bottom
、center
以及top left
、top right
、bottom right
、bottom left
- 也可以通过百分比、数值分别设定在 \(x\) 与 \(y\) 轴构成的坐标
- 默认取值包括
(1)scale
- 通过放缩元素的宽高,改变元素的尺寸
scaleX()
:改变元素宽度,大于 \(1\) 表示放大倍数,\(0-1\) 之间表示缩小倍率(下同)scaleY()
:改变元素高度scale()
:一个值表示同时改变元素的宽高,两个值表示同时分别改变元素的宽度与高度
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
div {
width: 300px;
height: 200px;
display: block;
margin: auto;
background-color: #ff7777;
transition: transform 1s linear;
}
div:hover {
transform: scale(1.5, 0.5);
}
</style>
</head>
<body>
<div></div>
</body>
</html>
(2)translate
-
通过平移的方式,改变元素的位置
-
二维变换
translateX()
:沿 \(x\) 轴方向移动,正值向右、负值向左translateY()
:沿 \(y\) 轴方向移动,正值向下、负值向上translate(x, y)
:同时沿 \(x\) 与 \(y\) 轴移动,第一个参数是 \(x\) 轴方向移动,第二个参数是 \(y\) 轴方向移动
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style> div { width: 300px; height: 200px; display: block; margin: auto; background-color: #ff7777; transition: transform 1s linear; } div:hover { transform: translate(-100px, 100px); } </style> </head> <body> <div></div> </body> </html>
-
三维变换
translateZ()
:沿 \(z\) 轴方向移动,正值向外、负值向内
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style> body { perspective: 1000px; // 设定人眼与屏幕的距离为 1000px(即人眼在 z 轴 1000px 处) } div { width: 300px; height: 200px; display: block; margin: auto; background-color: #ff7777; transform-origin: bottom left; transition: transform 1s linear; } div:hover { transform: translateZ(300px); // 效果看起来是放大(即近大远小)大于到人眼的距离时会消失 } </style> </head> <body> <div></div> </body> </html>
(3)rotate
-
通过旋转,改变元素的角度
-
二维变换
rotate()
:默认以元素中心为中心,旋转指定角度(deg)、指定梯度(grad)或旋转圈数(turn),正值顺时针、负值逆时针
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style> div { width: 300px; height: 200px; display: block; margin: auto; background-color: #ff7777; transition: transform 1s linear; } div:hover { transform: rotate(1turn); } </style> </head> <body> <div></div> </body> </html>
-
三维变换
rotateX()
:沿 \(x\) 轴旋转,正负值旋转方向不同(下同)rotateY()
:沿 \(y\) 轴旋转rotateZ()
:沿 \(z\) 轴旋转
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style> body { perspective: 1000px; } div { width: 300px; height: 200px; display: block; margin: auto; background-color: #ff7777; transition: transform 1s linear; } div:hover { transform: rotateX(30deg); } </style> </head> <body> <div></div> </body> </html>
(4)skew
- 通过根据 \(x\) 轴或 \(y\) 轴倾斜,改变元素的形状
skewX()
:在 \(x\) 轴方向上倾斜指定角度,正负值方向不同(下同)skewX()
:在 \(y\) 轴方向上倾斜指定角度skew(x, y)
:同时分别改变元素在 \(x\) 与 \(y\) 轴上的倾斜
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body {
perspective: 1000px;
}
div {
width: 300px;
height: 200px;
display: block;
margin: auto;
background-color: #ff7777;
transition: transform 1s linear;
}
div:hover {
transform: skewX(30deg);
}
</style>
</head>
<body>
<div></div>
</body>
</html>
(5)案例
a. 旋入
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body {
height: 100vh;
display: flex;
}
a {
text-decoration: none;
margin: auto;
border: 3px solid black;
padding: 30px 80px;
font-size: 30px;
font-weight: bolder;
position: relative;
overflow: hidden;
}
a::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 105%;
height: 100%;
background-color: #ff7777;
z-index: -1;
transition: transform 0.5s ease-out;
transform-origin: bottom left;
transform: rotate(-90deg);
}
a:hover::before {
transform: rotate(0deg);
}
</style>
</head>
<body>
<a>Hover me</a>
</body>
</html>
b. 滑入
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body {
height: 100vh;
display: flex;
}
a {
text-decoration: none;
margin: auto;
border: 3px solid black;
padding: 30px 80px;
font-size: 30px;
font-weight: bolder;
color: #ff7777;
position: relative;
overflow: hidden;
transition: all 1s ease-out;
}
a::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #ff7777;
z-index: -1;
transition: all 0.5s ease-out;
transform: translateX(-100%);
}
a:hover {
color: white;
}
a:hover::before {
transform: translateX(0);
}
</style>
</head>
<body>
<a>Hover me</a>
</body>
</html>
-
带入文字
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style> body { height: 100vh; display: flex; } a { text-decoration: none; margin: auto; border: 3px solid black; padding: 30px 80px; font-size: 30px; font-weight: bolder; color: #ff7777; position: relative; overflow: hidden; } a::before { content: "YEAH!"; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: #ff7777; color: white; transition: all 0.5s ease-out; transform: translateY(-100%); display: flex; align-items: center; justify-content: center; } a:hover::before { transform: translateY(0); } </style> </head> <body> <a>Hover me</a> </body> </html>
-
伪闪光滑入
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style> body { height: 100vh; background-color: #333; display: flex; } a { text-decoration: none; margin: auto; border: 3px solid black; padding: 30px 80px; font-size: 30px; font-weight: bolder; color: #ff7777; position: relative; overflow: hidden; transition: all 0.5s ease-out; } a::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 50%; background-color: white; z-index: -1; transition: all 0.5s ease-out; transform: translateX(-100%) rotate(45deg); } a:hover { background-color: #ff7777; color: white; } a:hover::before { transform: translateX(100%) rotate(45deg); } </style> </head> <body> <a>Hover me</a> </body> </html>
c. 十字扩展(三维变换)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body {
height: 100vh;
display: flex;
}
a {
text-decoration: none;
margin: auto;
border: 3px solid black;
padding: 30px 80px;
font-size: 30px;
font-weight: bolder;
color: #ff7777;
position: relative;
overflow: hidden;
transition: all 1s ease-out;
}
a::before,
a::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #ff7777;
z-index: -1;
transition: all 0.5s ease-out;
}
a::before {
transform: rotateX(90deg);
}
a::after {
transform: rotateY(90deg);
}
a:hover {
color: white;
}
a:hover::before {
transform: rotateX(0);
}
a:hover::after {
transform: rotateY(0);
}
</style>
</head>
<body>
<a>Hover me</a>
</body>
</html>
-
文字放大退出
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style> body { height: 100vh; display: flex; } a { perspective: 500px; text-decoration: none; margin: auto; border: 3px solid black; padding: 30px 80px; font-size: 30px; font-weight: bolder; color: #ff7777; position: relative; overflow: hidden; transition: all 0.5s ease-out; } a::before { content: "Hover me"; font-size: 30px; font-weight: bolder; color: white; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: #ff7777; z-index: -1; transition: all 0.5s ease-out; transform: translateZ(800px); display: flex; align-items: center; justify-content: center; } a:hover { color: white; } a:hover::before { transform: translateZ(0); } </style> </head> <body> <a>Hover me</a> </body> </html>
-
切牌
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style> body { height: 100vh; display: flex; } a { text-decoration: none; margin: auto; border: 3px solid black; padding: 30px 80px; font-size: 30px; font-weight: bolder; color: transparent; position: relative; overflow: hidden; } a::before, a::after { content: "Hover me"; font-size: 30px; font-weight: bolder; color: white; position: absolute; top: 0; width: 100%; height: 100%; background-color: #ff7777; transition: all 0.5s ease-out; display: flex; align-items: center; justify-content: center; } a::before { left: 0; } a::after { left: -100%; } a::before { transform: rotateY(0deg) scale(1); } a::after { transform: rotateY(360deg) scale(0); } a:hover::before { left: 100%; transform: rotateY(360deg) scale(0); opacity: 0; } a:hover::after { left: 0; transform: rotateY(0) scale(1); opacity: 1; } </style> </head> <body> <a>Hover me</a> </body> </html>
d. 点入后放大
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body {
height: 100vh;
display: flex;
}
a {
text-decoration: none;
margin: auto;
padding: 30px;
font-size: 30px;
font-weight: bolder;
color: #ff7777;
position: relative;
overflow: hidden;
transition: all 0.5s ease-out 0.5s;
}
a::before,
a::after {
content: "";
position: absolute;
top: 50%;
width: 20px;
height: 20px;
border-radius: 50%;
transform: translateY(-50%);
background-color: transparent;
z-index: -1;
transition: all 0.5s ease-out;
}
a::before {
left: 0;
box-shadow: -100px 0 0 #ff7777;
}
a::after {
right: 0;
box-shadow: 100px 0 0 #ff7777;
}
a:hover {
color: white;
background-color: #ff7777;
}
a:hover::before {
left: 50%;
background-color: #ff7777;
box-shadow: -30px 0 0 #ff7777;
transform: translateX(-50%) translateY(-50%);
}
a:hover::after {
right: 50%;
background-color: #ff7777;
box-shadow: 30px 0 0 #ff7777;
transform: translateX(50%) translateY(-50%);
}
</style>
</head>
<body>
<a>Hover me</a>
</body>
</html>
f. 取景框
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body {
height: 100vh;
display: flex;
}
a {
text-decoration: none;
margin: auto;
padding: 30px;
font-size: 30px;
font-weight: bolder;
color: #ff7777;
position: relative;
transition: all 0.5s ease-out 0.5s;
}
a::before,
a::after {
content: "";
position: absolute;
width: 30px;
height: 30px;
background-color: transparent;
z-index: -1;
transition: all 0.5s ease-out;
}
a::before {
top: -5px;
left: -5px;
border-top: 3px solid #ff7777;
border-left: 3px solid #ff7777;
}
a::after {
right: -5px;
bottom: -5px;
border-right: 3px solid #ff7777;
border-bottom: 3px solid #ff7777;
}
a:hover {
color: white;
background-color: #ff7777;
}
a:hover::before,
a:hover::after {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<a>Hover me</a>
</body>
</html>
0x03 动画与关键帧 animation & keyframes
(1)基本使用
- 使用步骤:
- 定义 CSS 动画规则(即关键帧)
- 将该动画添加到需要动画的元素上
@keyframes identifier
:定义关键帧animation-name
:通过名称使用相应的动画animation-duration
:动画持续时间
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
div {
width: 100px;
height: 100px;
display: block;
background-color: #ff7777;
}
div:hover {
animation-name: moving;
animation-duration: 3s;
}
@keyframes moving {
0% {
transform: translate(0);
}
30% {
transform: translate(150px);
}
100% {
transform: translate(300px);
}
}
</style>
</head>
<body>
<div></div>
</body>
</html>
(2)其他属性
animation-fill-mode
:填充模式,设置 CSS 动画在执行之前和之后如何将样式应用于其目标(详解)none
、forward
、backward
、both
animation-iteration-count
:迭代次数,设置 CSS 动画重复执行次数- 取值
infinite
表示无限重复
- 取值
animation-timing-function
:时序函数,与transition-timing-function
类似animation-direction
:动画方向reverse
:逆向alternate
:交替alternate-reverse
:逆向交替
animation-delay
:延时
(3)缩写属性
animation: name duration ...args
...args
表示其他属性,没有规定顺序
(4)案例:牛顿摆
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body {
height: 100vh;
background-color: #333;
display: flex;
align-items: center;
justify-content: center;
}
div {
display: flex;
border-top: 10px solid white;
}
span {
display: block;
width: 3px;
height: 300px;
background-color: white;
margin: 0 30px;
position: relative;
transform-origin: top;
}
span::before {
content: '';
position: absolute;
left: 0;
bottom: 0;
width: 60px;
aspect-ratio: 1;
border-radius: 50%;
background-color: white;
transform: translateX(-50%);
}
span:first-child {
animation: left 2s ease-in infinite;
}
span:last-child {
animation: right 2s ease-in infinite;
}
@keyframes left {
0% { transform: rotate(0deg); }
25% { transform: rotate(60deg); }
50% { transform: rotate(0deg); }
100% { transform: rotate(0deg); }
}
@keyframes right {
0% { transform: rotate(0deg); }
50% { transform: rotate(0deg); }
75% { transform: rotate(-60deg); }
100% { transform: rotate(0deg); }
}
</style>
</head>
<body>
<div>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</body>
</html>
-End-