3、CSS关键帧动画:@keyframes规则、animation属性、动画填充模式
好,咱们今天来聊聊CSS关键帧动画。说实话,这是我在移动端开发中最喜欢用的动画方式之一。为什么?因为它不需要引入任何第三方库,浏览器原生支持,性能也相当不错。
我记得刚入行那会儿,做动画还全靠JavaScript定时器,一个不小心就卡成PPT。后来CSS动画普及了,我才发现——原来让元素动起来可以这么简单。
3.1 @keyframes规则:定义动画的“剧本”
@keyframes 说白了就是给动画写剧本。你告诉浏览器:从哪开始、到哪结束、中间经过哪些关键位置。浏览器会自动帮你算出中间的所有过渡帧。
来看一个最基本的例子:
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
这里 from 代表 0% 时刻,to 代表 100% 时刻。你也可以用百分比来控制更精细的阶段:
@keyframes bounce {
0% {
transform: translateY(0);
}
50% {
transform: translateY(-30px);
}
100% {
transform: translateY(0);
}
}
我在项目中遇到过一个问题:有些同学喜欢把 @keyframes 写在媒体查询里面,结果动画死活不生效。嗯,这里要注意——@keyframes 是全局规则,不能嵌套在 @media 里。
3.2 animation属性:让动画跑起来
有了剧本,还得有导演来喊“Action”。animation 属性就是那个导演。
它是一个简写属性,包含以下子属性:
| 子属性 | 说明 | 默认值 |
|---|---|---|
| animation-name | 指定 @keyframes 的名称 | none |
| animation-duration | 动画完成一个周期的时间 | 0s |
| animation-timing-function | 动画的速度曲线 | ease |
| animation-delay | 动画开始前的延迟时间 | 0s |
| animation-iteration-count | 动画播放次数 | 1 |
| animation-direction | 动画是否反向播放 | normal |
| animation-fill-mode | 动画结束后的样式状态 | none |
| animation-play-state | 动画的播放状态 | running |
我个人习惯这样写简写形式:
.element {
animation: bounce 1s ease-in-out 0.5s infinite alternate;
}
这个顺序是:名称、时长、缓动函数、延迟、播放次数、方向。你想想看,如果记不住顺序怎么办?我建议你拆开来写,可读性更好:
.element {
animation-name: bounce;
animation-duration: 1s;
animation-timing-function: ease-in-out;
animation-delay: 0.5s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
3.3 动画填充模式:动画结束后的“归宿”
这个知识点坑很多,我重点讲讲。
animation-fill-mode 控制的是:动画开始前和结束后,元素应该处于什么状态。它有四个值:
- none(默认):动画结束后回到原始样式
- forwards:动画结束后保持最后一帧的样式
- backwards:动画开始前(延迟期间)应用第一帧的样式
- both:同时应用 forwards 和 backwards 的效果
举个例子你就明白了:
@keyframes slideIn {
from {
transform: translateX(-100px);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.box {
/* 默认 none:动画结束后,元素瞬间回到原始位置 */
animation: slideIn 1s;
}
.box-forwards {
/* forwards:动画结束后,元素保持在终点位置 */
animation: slideIn 1s forwards;
}
我曾经在做一个弹窗动画时踩过坑。弹窗从屏幕外滑入,动画结束后我希望它停在屏幕中央。结果忘了加 forwards,弹窗滑进来又瞬间消失了。排查了半天才发现是 fill-mode 的问题。
3.4 实战:一个完整的加载动画
咱们把上面学的知识串起来,做一个简单的加载动画:
@keyframes pulse {
0%, 100% {
transform: scale(1);
opacity: 0.5;
}
50% {
transform: scale(1.2);
opacity: 1;
}
}
.loading-dot {
width: 12px;
height: 12px;
border-radius: 50%;
background: #409eff;
animation: pulse 1.2s ease-in-out infinite;
}
/* 让三个点依次延迟播放 */
.loading-dot:nth-child(2) {
animation-delay: 0.2s;
}
.loading-dot:nth-child(3) {
animation-delay: 0.4s;
}
这里用了 infinite 让动画无限循环,配合 animation-delay 实现错落有致的节奏感。说白了就是让三个点像呼吸一样此起彼伏。
3.5 多动画叠加
一个元素可以同时应用多个动画,用逗号分隔就行:
.element {
animation:
fadeIn 1s ease-out,
bounce 0.5s ease-in-out 1s;
}
这样元素先淡入,1秒后开始弹跳。我在做引导页动画时经常用这个技巧,让多个动画串行播放,效果很自然。
好了,关于 CSS 关键帧动画的核心内容就这些。记住:@keyframes 是剧本,animation 是导演,fill-mode 是结局。把这三点吃透了,移动端的大部分动画需求你都能搞定。