CSS 动画

目录

一、核心概念与语法

[1. @keyframes 关键帧](#1. @keyframes 关键帧)

[2. animation 属性](#2. animation 属性)

二、动画调速函数(animation-timing-function)

[1. 预设值](#1. 预设值)

[2. 贝塞尔曲线](#2. 贝塞尔曲线)

[3. 步进函数(steps())](#3. 步进函数(steps()))

三、动画控制与交互

[1. 暂停与恢复](#1. 暂停与恢复)

[2. JavaScript 控制](#2. JavaScript 控制)

3.逐帧动画与精灵图

四、性能优化

五、实际应用示例

[1. 淡入淡出效果](#1. 淡入淡出效果)

[2. 旋转加载图标](#2. 旋转加载图标)

[3. 弹跳效果](#3. 弹跳效果)

六、兼容性与前缀

示例:走马灯

示例:全民出游季


CSS 动画允许通过定义关键帧(@keyframes)和动画属性(animation)实现复杂的动态效果,相比 transition 更灵活,支持多阶段控制和循环播放。


一、核心概念与语法

在 CSS 中,以 @ 开头的语法称为 At-Rules(规则声明),用于定义 CSS 的元数据、条件逻辑、外部资源引入等高级功能。

1. @keyframes 关键帧

  • 作用:定义动画的中间状态。

  • 语法

    css 复制代码
    @keyframes 动画名称 {
      from { /* 初始状态 */ }
      to { /* 结束状态 */ }
      /* 或使用百分比 */
      0% { ... }
      50% { ... }
      100% { ... }
    }
  • 示例

    css 复制代码
    @keyframes fadeIn {
      from { opacity: 0; }
      to { opacity: 1; }
    }
    
    @keyframes slideAndRotate {
      0% { transform: translateX(0) rotate(0); }
      50% { transform: translateX(200px) rotate(180deg); }
      100% { transform: translateX(0) rotate(360deg); }
    }

2. animation 属性

  • 作用:将关键帧动画应用到元素。

  • 子属性

    属性 作用 常用值
    animation-name 指定关键帧名称 fadeIn, slideAndRotate
    animation-duration 动画持续时间 2s, 500ms
    animation-timing-function 速度曲线 ease(默认), linear, ease-in-out, cubic-bezier(0.4, 0, 0.2, 1)
    animation-delay 动画延迟时间 1s, 0.5s
    animation-iteration-count 播放次数 1(默认), infinite, 3
    animation-direction 播放方向 normal(默认正向), reverse(反向), alternate(正反交替)
    animation-fill-mode 动画结束后的样式保留 none(默认), forwards(保持最后一帧), backwards(应用第一帧)
    animation-play-state 控制播放状态 running(默认), paused(暂停)
  • 简写语法

    css 复制代码
    .element {
      animation: name duration timing-function delay iteration-count direction fill-mode play-state;
    }

    示例

    css 复制代码
    .box {
      animation: fadeIn 2s ease-in-out 1s infinite alternate forwards;
    }

二、动画调速函数(animation-timing-function

1. 预设值

  • ease:默认缓入缓出(先加速后减速)。

  • linear:匀速。

  • ease-in:缓入(逐渐加速)。

  • ease-out:缓出(逐渐减速)。

  • ease-in-out:缓入缓出。

2. 贝塞尔曲线

  • 使用 cubic-bezier(x1, y1, x2, y2) 自定义速度曲线。
css 复制代码
.box {
  animation-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55);
}

3. 步进函数(steps()

  • 将动画拆分为固定步数播放,适合帧动画。

    css 复制代码
    .box {
      animation-timing-function: steps(5, jump-start); /* 分 5 步跳跃播放 */
    }

三、动画控制与交互

1. 暂停与恢复

  • 通过 animation-play-state 控制:

    css 复制代码
    .box:hover {
      animation-play-state: paused; /* 悬停时暂停动画 */
    }

2. JavaScript 控制

  • 动态添加/移除动画类:

    css 复制代码
    const box = document.querySelector('.box');
    box.classList.add('fadeIn');  // 触发动画
    box.style.animation = 'none'; // 停止动画

3.逐帧动画与精灵图

css 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test</title>
    <link rel="stylesheet" href="./iconfont/iconfont.css">
    <style>

        .box {
            margin: 100px auto;
            width: 1000px;
        }

        .people {
            width: 140px;
            height: 140px;
            background-image: url(./res/run.png);

            animation: 
                run 1s steps(12) infinite,
                move 4s linear infinite;
        }

        @keyframes run {
            from {
                background-position: 0 0;
            }
            
            to {
                background-position: -1680px 0;
            }
        }

        @keyframes move {
            0% {
                transform: translate(0) scaleX(1);
            }
            
            50% {
                transform: translate(800px) scaleX(1);
            }

            50.1% {
                transform: translate(800px) scaleX(-1);
            }

            100% {
                transform: translate(0) scaleX(-1);
            }

        }

    </style>
</head>
<body>
    <div class="box">
        <div class="people"></div>
    </div>

</body>
</html>

四、性能优化

  1. 优先使用 transformopacity

    • 这些属性由 GPU 加速,避免触发重排(如 widthmargin)。
  2. 减少动画数量

    • 同时运行过多动画可能导致页面卡顿。
  3. 使用 will-change 提示浏览器

    css 复制代码
    .box {
      will-change: transform, opacity; /* 提前告知浏览器可能变化的属性 */
    }

五、实际应用示例

1. 淡入淡出效果

css 复制代码
@keyframes fadeInOut {
  0%, 100% { opacity: 0; }
  50% { opacity: 1; }
}

.element {
  animation: fadeInOut 3s ease-in-out infinite;
}

2. 旋转加载图标

css 复制代码
@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.loader {
  animation: spin 1s linear infinite;
}

3. 弹跳效果

css 复制代码
@keyframes bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-30px); }
}

.button {
  animation: bounce 1s ease-in-out infinite;
}

六、兼容性与前缀

  • 现代浏览器:无需前缀(Chrome 43+、Firefox 16+、Safari 9+)。

  • 旧版浏览器 :需添加 -webkit- 前缀:

    css 复制代码
    @-webkit-keyframes fadeIn { ... }
    .box {
      -webkit-animation: fadeIn 2s;
    }

示例:走马灯

css 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test</title>
    <link rel="stylesheet" href="./iconfont/iconfont.css">
    <style>

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        li {
            list-style: none;
        }

        a {
            text-decoration: none;
            color: #fff;
        }

        .box {
            margin: 100px auto;

            width: 300px;
            height: 50px;
            overflow: hidden;
        }

        .box ul {
            display: flex;
            animation: move 7s linear infinite;
        }

        .box:hover ul {
            animation-play-state: paused;
        }

        @keyframes move {
            from {
                transform: translateX(0);
            }
            to {
                transform: translateX(-700px);
            }
        }

        .box img {
            width: 100px;
        }

    </style>
</head>
<body>
    <div class="box">
        <ul>
            <li><img src="./res/1.jpg" alt=""></li>
            <li><img src="./res/2.jpg" alt=""></li>
            <li><img src="./res/3.jpg" alt=""></li>
            <li><img src="./res/4.jpg" alt=""></li>
            <li><img src="./res/5.jpg" alt=""></li>
            <li><img src="./res/6.jpg" alt=""></li>
            <li><img src="./res/7.jpg" alt=""></li>
            <!-- 填补显示区域的空白 -->
            <li><img src="./res/1.jpg" alt=""></li>
            <li><img src="./res/2.jpg" alt=""></li>
            <li><img src="./res/3.jpg" alt=""></li>
        </ul>
    </div>

</body>
</html>

示例:全民出游季

css 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test</title>
    <link rel="stylesheet" href="./iconfont/iconfont.css">
    <style>

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        li {
            list-style: none;
        }

        a {
            text-decoration: none;
            color: #fff;
        }

        html {
            height: 100%;   
        }

        body {
            height: 100%;
            background: url(./res/images/f1_1.jpg) no-repeat center 0 / cover;   
        }

        .cover {
            width: 100%;
            height: 100%;   
            position: relative;
        }

        .cover div {
            position: absolute;
        }

        .title {
            top: 50%;
            left: 50%;
            transform: translate(-50%,-50%);
            animation: show 1s;
        }

        @keyframes show {
            0% {
                transform: translate(-50%,-50%) scale(1);
            }
            20% {
                transform: translate(-50%,-50%) scale(0.3);
            }
            50% {
                transform: translate(-50%,-50%) scale(1.7);
            }
            80% {
                transform: translate(-50%,-50%) scale(0.8);
            }
            100% {
                transform: translate(-50%,-50%) scale(1);
            }
        }

        .label {
            bottom: 10%;
            left: 50%;
            transform: translate(-50%);
        }

        .label ul {
            display: flex;
            justify-content: space-between;
        }

        .label ul img {
            width: 100px;
            margin: 0 85px;
            animation: bounce .8s ease-in infinite alternate;
        }

        .label ul li:nth-child(2) img {
            animation: bounce .8s 0.3s ease-in infinite alternate;
        }

        .label ul li:nth-child(3) img {
            animation: bounce .8s 0.6s ease-in infinite alternate;
        }

        .label ul li:nth-child(4) img {
            animation: bounce .8s 0.9s ease-in infinite alternate;
        }

        @keyframes bounce {
            from {
                transform: translateY(0);
            }

            to {
                transform: translateY(30px);
            }
        }
        
        .cloud {
            position: relative;
            left: 50%;
        }

        .cloud img:nth-child(1) {
            top: 20px;
            margin-left: -200px;
        }

        .cloud img:nth-child(2) {
            top: 100px;
            margin-left: 400px;
        }

        .cloud img:nth-child(3) {
            top: 180px;
            margin-left: -500px;
        }

        .cloud img {
            position: absolute;
            animation: move 2s linear infinite alternate;
        }

        @keyframes move {
            to {
                transform: translate(-50px);
            }
        }

        .lu {
            top: 15%;
            left: 60%;
        }
        
        .san {
            top: 15%;
            left: 25%;
            animation: float 1.5s linear infinite alternate;
        }

        @keyframes float {
            to {
                transform: translateY(50px);
            }
        }

    </style>
</head>
<body>
    <div class="cover">
        <div class="cloud">
            <img src="./res/images/yun1.png" alt="">
            <img src="./res/images/yun2.png" alt="">
            <img src="./res/images/yun3.png" alt="">
        </div>    
        <div class="lu"><img src="./res/images/lu.png" alt=""></div>    
        <div class="san"><img src="./res/images/san.png" alt=""></div>
        <div class="label">
            <ul>
                <li><img src="./res/images/1.png" alt=""></li>
                <li><img src="./res/images/2.png" alt=""></li>
                <li><img src="./res/images/3.png" alt=""></li>
                <li><img src="./res/images/4.png" alt=""></li>
            </ul>
        </div>
        <div class="title"><img src="./res/images/font1.png" alt=""></div>

    </div>

</body>
</html>
相关推荐
跟着汪老师学编程2 分钟前
24、web前端开发之CSS3(一)
前端·css·css3
beibeibeiooo8 分钟前
【CSS3】01-初始CSS + 引入 + 选择器 + div盒子 + 字体修饰
前端·css·css3
孤╮独的美15 分钟前
CSS3:深度解析与实战应用
前端·css·css3
一城烟雨_24 分钟前
Vue3 实现pdf预览
前端·vue.js·pdf
易xingxing28 分钟前
探索HTML5 Canvas:创造动态与交互性网页内容的强大工具
前端·html·html5
好_快37 分钟前
Lodash源码阅读-arrayPush
前端·javascript·源码阅读
好_快39 分钟前
Lodash源码阅读-equalByTag
前端·javascript·源码阅读
大土豆的bug记录6 小时前
鸿蒙进行视频上传,使用 request.uploadFile方法
开发语言·前端·华为·arkts·鸿蒙·arkui
maybe02096 小时前
前端表格数据导出Excel文件方法,列自适应宽度、增加合计、自定义文件名称
前端·javascript·excel·js·大前端
HBR666_6 小时前
菜单(路由)权限&按钮权限&路由进度条
前端·vue