《CSS新世界》5 更强的视觉表现
5.4 动画
5.4.1 animation
CSS animation 属性是 animation-name
,animation-duration
, animation-timing-function
,animation-delay
,animation-iteration-count
,animation-direction
,animation-fill-mode
和 animation-play-state
属性的一个简写属性形式。
animation-timing-function
属性设置动画在每个周期的持续时间内如何进行。
animation-timing-function
属于 [<easing-function>
](%5Bhttps://developer.mozilla.org/zh-CN/docs/Web/CSS/easing-function%5B%3Ceasing-function%5D(https://developer.mozilla.org/zh-CN/docs/Web/CSS/easing-function[<easing-function)> - CSS:层叠样式表 | MDN](
等同于 cubic-bezier(0.25, 0.1, 0.25, 1.0)
,即默认值,表示动画在中间加速,在结束时减速。
等同于 cubic-bezier(0.42, 0, 1.0, 1.0)
,表示动画一开始较慢,随着动画属性的变化逐渐加速,直至完成。
等同于 cubic-bezier(0, 0, 0.58, 1.0)
,表示动画一开始较快,随着动画的进行逐渐减速。
等同于 cubic-bezier(0.42, 0, 0.58, 1.0)
,表示动画属性一开始缓慢变化,随后加速变化,最后再次减速变化。
- ease:
- 描述:开始时速度较慢,然后加速,最后再减速。
- 速度变化:慢 -> 快 -> 慢
- 这是一个默认的过渡效果,它模拟了物体在物理空间中自然运动的方式,开始时需要一些力量来克服静止,然后加速,最后因为阻力或能量的减少而减速。
- ease-in:
- 描述:开始时速度较慢,然后逐渐加速。
- 速度变化:慢 -> 快
- 这种效果使得动画在开始时看起来比较“沉重”或“迟钝”,然后逐渐加速,直到结束。
- ease-out:
- 描述:开始时速度较快,然后逐渐减速。
- 速度变化:快 -> 慢
- 与ease-in相反,ease-out效果使得动画在开始时看起来比较“轻快”,然后逐渐减速,给人一种“平稳降落”的感觉。
- ease-in-out:
- 描述:开始时速度较慢,中间加速,然后再减速。
- 速度变化:慢 -> 快 -> 慢
- 这是ease的变体,但通常比单纯的ease更加平滑,因为它在动画的开始和结束时都进行了平滑的过渡。
等同于 cubic-bezier(0.0, 0.0, 1.0, 1.0)
,表示动画以匀速运动。
开发者自定义的三次贝塞尔曲线,其中 p1 和 p3 的值必须在 0 到 1 的范围内。
/* 线性函数和关键字 */
/* linear(<point-list>) */
linear(1, -0.5, 0)
linear
/* 三次贝塞尔函数和关键字 */
/* cubic-bezier(<x1>, <y1>, <x2>, <y2>) */
cubic-bezier(0.42, 0.0, 1.0, 1.0)
ease
ease-in
ease-out
ease-in-out
/* 阶跃函数和关键字 */
/* steps(<number-of-steps>, <direction>) */
steps(4, end)
step-start
step-end
animation-timing-function
/* @keyframes duration | easing-function | delay |
iteration-count | direction | fill-mode | play-state | name */
animation: 3s ease-in 1s 2 reverse both paused slidein;
/* @keyframes duration | easing-function | delay | name */
animation: 3s linear 1s slidein;
/* two animations */
animation:
3s linear slidein,
3s ease-out 5s slideout;
5.4.2 @keyframes
@keyframes <keyframes-name> {
<keyframes-bock-list>
}
1 起止帧可以不设置
@keyframes fadeIn {
100% {
margin-top: 150px;
}
}
2 关键帧可以合并
@keyframes identifier {
0% {
top: 0;
left: 0;
}
30% {
top: 50px;
}
68%,
72% {
left: 50px;
}
100% {
top: 100px;
left: 100%;
}
}
3 !important 无效
@keyframes important1 {
from {
margin-top: 50px;
}
50% {
margin-top: 150px !important;
} /* 忽略 */
to {
margin-top: 100px;
}
}
5.4.4 animation-delay 负延时与即时播放效果
动画到元素开始执行动画之前等待的时间量。动画可以稍后开始、立即从开头开始或立即开始并在动画中途播放。
正值表示动画应在指定的时间量过去后开始。默认值为
0s
,表示动画应立即开始。负值会导致动画立即开始,但是从动画循环的某个时间点开始。
例如,如果你将
-1s
作为动画延迟时间,则动画将立即开始,但是将在动画序列的第 1 秒开始。如果你为动画延迟指定负值,但起始值是隐含的,则起始值取自应用动画到元素的时刻。
/* 单个动画 */
animation-delay: 3s;
animation-delay: 0s;
animation-delay: -1500ms;
/* 多个动画 */
animation-delay: 2.1s, 480ms;
/* 全局值 */
animation-delay: inherit;
animation-delay: initial;
animation-delay: revert;
animation-delay: revert-layer;
animation-delay: unset;
5.4.5 animation-direction 方向
设置动画在每次运行完后是反向运行还是重新回到开始位置重复运行。
动画在每个循环中正向播放。换句话说,每次动画循环时,动画将重置为起始状态并重新开始。这是默认值。
动画在每个循环中反向播放。换句话说,每次动画循环时,动画将重置为结束状态并重新开始。动画步骤将反向执行,并且时间函数也将被反转。例如,ease-in
时间函数变为 ease-out
。
动画在每个循环中正反交替播放,第一次迭代是正向播放。确定循环是奇数还是偶数的计数从 1 开始。
动画在每个循环中正反交替播放,第一次迭代是反向播放。确定循环是奇数还是偶数的计数从 1 开始。
/* 单个动画 */
animation-direction: normal;
animation-direction: reverse;
animation-direction: alternate;
animation-direction: alternate-reverse;
/* 多个动画 */
animation-direction: normal, reverse;
animation-direction: alternate, reverse, normal;
/* 全局值 */
animation-direction: inherit;
animation-direction: initial;
animation-direction: revert;
animation-direction: revert-layer;
animation-direction: unset;
5.4.6 animation-iteration-count 播放次数
默认为 1
,设置动画重复次数,可以指定 infinite 无限次重复动画
设置动画一个周期的时长。
/* 关键字值:无限循环 */
animation-iteration-count: infinite;
/* 数字值 */
animation-iteration-count: 0; /* 重置animation属性 */
animation-iteration-count: 3;
animation-iteration-count: 1.5; /*第2轮,播放一般停止*/
/* 多个值 */
animation-iteration-count: 2, 0, infinite;
/* 全局值 */
animation-iteration-count: inherit;
animation-iteration-count: initial;
animation-iteration-count: revert;
animation-iteration-count: revert-layer;
animation-iteration-count: unset;
例子
禁用状态透明度不用设置 opacity:0.4
, 采用animation-iteration-count
小数的方式,达到同样的效果,
为了达到opacity:1
的40%,可以设置0.4
的进度。
.visible:disabled {
animation: fadeIn 1s .4 both;
}
animation-iteration-count小数作用示意 » CSS新世界demo演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
input {
opacity: 0;
border: 1px solid darkgray;
}
.visible {
animation: fadeIn 0.25s both;
}
.visible:disabled {
animation: fadeIn 1s 0.4 both;
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
</style>
<script>
window.onload = function () {
var button = document.getElementById("button");
var inputs = document.querySelectorAll("input");
button.onclick = function () {
inputs.forEach(function (input) {
input.classList.add("visible");
input.classList.remove("hidden");
});
};
};
</script>
</head>
<body>
<div class="demo">
<p><button id="button">输入框显示</button></p>
<p><input value="可用" /></p>
<p><input value="禁用" disabled="" /></p>
</div>
</body>
</html>
5.4.7 animation-fill-mode 动画填充模式
指定动画执行前后如何为目标元素应用样式
/* Single animation */
animation-fill-mode: none;
animation-fill-mode: forwards;
animation-fill-mode: backwards;
animation-fill-mode: both; /*解决大多数情况*/
/* Multiple animations */
animation-fill-mode: none, backwards;
animation-fill-mode: both, forwards, none;
例子
.element {
opacity: 0.5;
animation: fadeIn 2s 1s; /* duration:2s delay:1s */
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
上面有透明度突变的糟糕体验
1 透明度 0.5,保持1s
2 透明度从0.5突变到0,然后从0逐渐过渡到1,过程持续2s.
3 透明度从1 突变到 0.5,并保持不变。(因为animation-iteration-count 默认为 1)
把时间比作尺子,理解如下
forwards
:
“前进”,动画结束后(animation-iteration-count 属性决定),元素应用当前结束时的属性值。
.element {
opacity: 0.5;
animation: fadeIn 2s 1s forwards; /* duration:2s delay:1s */
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
- 透明度0.5, 保持1s.
- 透明度从0.5突变到0,动画使元素的透明度从0平滑过渡到1,持续2秒。
- 最后的结果透明度为1(动画结束后保持完全不透明(由于
forwards
关键字)).
backwards
:
“后退”,动画开始之前,元素应用动画第一轮播放的第一帧属性值。
.element {
opacity: 0.5;
animation: fadeIn 2s 1s backwards; /* duration:2s delay:1s */
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
- 透明度0, 保持1s. (
backwards
作用, 第1帧opacity: 0
)- 透明度从0.5突变到0,动画使元素的透明度从0平滑过渡到1,持续2秒。
- 透明度从1 突变到 0.5,并保持不变。