pin_drop当前位置:知识文库 ❯ 图文

CSS集成:CSS动画详解 - @keyframes与animation属性完整指南

一、教程简介

CSS animation 属性结合 @keyframes 规则,可以创建复杂的连续动画效果,无需 JavaScript 即可实现旋转、弹跳、淡入淡出等丰富动画。与 transition 只能在状态变化时触发不同,animation 可以自动播放、循环播放,并精确控制动画的每个关键帧。本教程将详细讲解 CSS 动画的语法、关键帧、子属性以及实战应用。

二、核心概念

@keyframes 语法

代码示例

/* 基本语法 */
@keyframes animationName {
    from { /* 起始状态 */ }
    to { /* 结束状态 */ }
}

/* 百分比关键帧 */
@keyframes animationName {
    0% { /* 起始状态 */ }
    25% { /* 25%时刻 */ }
    50% { /* 中间状态 */ }
    75% { /* 75%时刻 */ }
    100% { /* 结束状态 */ }
}

/* 示例:弹跳动画 */
@keyframes bounce {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-30px); }
}

/* 示例:旋转动画 */
@keyframes spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

animation 简写属性

代码示例

/* 完整简写 */
animation: name duration timing-function delay iteration-count direction fill-mode play-state;

/* 示例 */
animation: bounce 1s ease 0s infinite alternate forwards running;

/* 常用简写 */
animation: spin 2s linear infinite;

animation 子属性

代码示例

/* 动画名称 */
animation-name: bounce;

/* 动画时长 */
animation-duration: 1s;
animation-duration: 500ms;

/* 时序函数 */
animation-timing-function: ease;
animation-timing-function: linear;
animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55);

/* 延迟 */
animation-delay: 0.2s;

/* 播放次数 */
animation-iteration-count: 1;       /* 播放1次 */
animation-iteration-count: 3;       /* 播放3次 */
animation-iteration-count: infinite; /* 无限循环 */

/* 播放方向 */
animation-direction: normal;            /* 正向 */
animation-direction: reverse;           /* 反向 */
animation-direction: alternate;         /* 正反交替 */
animation-direction: alternate-reverse; /* 反正交替 */

/* 填充模式 */
animation-fill-mode: none;      /* 不填充 */
animation-fill-mode: forwards;  /* 保持结束状态 */
animation-fill-mode: backwards; /* 应用起始状态 */
animation-fill-mode: both;      /* 同时应用 */

/* 播放状态 */
animation-play-state: running;  /* 播放 */
animation-play-state: paused;   /* 暂停 */

多动画

代码示例

/* 同时应用多个动画 */
animation: spin 2s linear infinite, pulse 1.5s ease infinite;

/* 分开写法 */
animation-name: spin, pulse;
animation-duration: 2s, 1.5s;
animation-timing-function: linear, ease;
animation-iteration-count: infinite, infinite;

三、代码示例

示例1:基础动画效果

代码示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>基础动画效果</title>
    <style>
        /* 旋转 */
        @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
        .anim-spin .box { animation: spin 2s linear infinite; }

        /* 弹跳 */
        @keyframes bounce { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-25px); } }
        .anim-bounce .box { animation: bounce 1s ease infinite; }

        /* 脉冲 */
        @keyframes pulse { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.15); opacity: 0.8; } }
        .anim-pulse .box { animation: pulse 1.5s ease infinite; }

        /* 摇晃 */
        @keyframes shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-8px); } 75% { transform: translateX(8px); } }
        .anim-shake .box { animation: shake 0.5s ease infinite; }

        /* 淡入淡出 */
        @keyframes fadeIO { 0%, 100% { opacity: 1; } 50% { opacity: 0.2; } }
        .anim-fade .box { animation: fadeIO 2s ease infinite; }

        /* 翻转 */
        @keyframes flip { 0% { transform: perspective(400px) rotateY(0); } 100% { transform: perspective(400px) rotateY(360deg); } }
        .anim-flip .box { animation: flip 2s ease-in-out infinite; }
    </style>
</head>
<body>
    <h1>基础动画效果</h1>
    <div class="demo-grid">
        <div class="demo-card anim-spin"><div class="box"></div><h3>旋转</h3></div>
        <div class="demo-card anim-bounce"><div class="box"></div><h3>弹跳</h3></div>
        <div class="demo-card anim-pulse"><div class="box"></div><h3>脉冲</h3></div>
        <div class="demo-card anim-shake"><div class="box"></div><h3>摇晃</h3></div>
        <div class="demo-card anim-fade"><div class="box"></div><h3>淡入淡出</h3></div>
        <div class="demo-card anim-flip"><div class="box"></div><h3>翻转</h3></div>
    </div>
</body>
</html>

示例2:animation-fill-mode与direction

代码示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>fill-mode与direction</title>
    <style>
        @keyframes moveRight {
            from { transform: translateX(0); background: #3498db; }
            to { transform: translateX(300px); background: #e74c3c; }
        }
        .fill-none .ball { animation: moveRight 2s ease none; }
        .fill-forwards .ball { animation: moveRight 2s ease forwards; }
        .fill-backwards .ball { animation: moveRight 2s ease 1s backwards; }
        .fill-both .ball { animation: moveRight 2s ease 1s both; }
        .dir-normal .ball { animation: moveRight 2s ease infinite normal; }
        .dir-reverse .ball { animation: moveRight 2s ease infinite reverse; }
        .dir-alternate .ball { animation: moveRight 2s ease infinite alternate; }
        .dir-alt-reverse .ball { animation: moveRight 2s ease infinite alternate-reverse; }
    </style>
</head>
<body>
    <h1>fill-mode 与 direction</h1>
    <h2>animation-fill-mode</h2>
    <div class="fill-none"><div class="track"><div class="ball"></div></div></div>
    <div class="fill-forwards"><div class="track"><div class="ball"></div></div></div>
    <h2>animation-direction</h2>
    <div class="dir-normal"><div class="track"><div class="ball"></div></div></div>
    <div class="dir-alternate"><div class="track"><div class="ball"></div></div></div>
</body>
</html>

示例3:动画实战应用

代码示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>动画实战应用</title>
    <style>
        /* 加载动画 */
        @keyframes spin { to { transform: rotate(360deg); } }
        .loader-spinner { border: 4px solid #ecf0f1; border-top-color: #3498db; border-radius: 50%; animation: spin 0.8s linear infinite; }

        @keyframes dotBounce { 0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; } 40% { transform: scale(1); opacity: 1; } }
        .loader-dots span { animation: dotBounce 1.4s ease-in-out infinite; }
        .loader-dots span:nth-child(2) { animation-delay: 0.16s; }
        .loader-dots span:nth-child(3) { animation-delay: 0.32s; }

        @keyframes barSlide { 0% { transform: translateX(-100%); } 100% { transform: translateX(350%); } }
        .loader-bar::after { animation: barSlide 1.2s ease infinite; }

        /* 通知动画 */
        @keyframes slideInRight { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
        .notification { animation: slideInRight 0.4s ease forwards; }

        /* 打字机效果 */
        @keyframes typewriter { from { width: 0; } to { width: 100%; } }
        @keyframes blink { 50% { border-color: transparent; } }
        .typewriter-text { animation: typewriter 3s steps(20) 0.5s forwards, blink 0.7s step-end infinite; }

        /* 浮动动画 */
        @keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
        .float-item { animation: float 3s ease-in-out infinite; }
        .float-item:nth-child(2) { animation-delay: 0.5s; }
        .float-item:nth-child(3) { animation-delay: 1s; }
    </style>
</head>
<body>
    <div class="container">
        <h1>动画实战应用</h1>
        <div class="section">
            <h2>加载动画</h2>
            <div class="loader-spinner"></div>
            <div class="loader-dots"><span></span><span></span><span></span></div>
            <div class="loader-bar"></div>
        </div>
        <div class="section">
            <h2>通知滑入动画</h2>
            <div class="notification notif-success">操作成功!</div>
        </div>
        <div class="section">
            <h2>打字机效果</h2>
            <div class="typewriter-text">Hello, CSS Animation World!</div>
        </div>
        <div class="section">
            <h2>浮动图标</h2>
            <div class="float-item">A</div>
            <div class="float-item">B</div>
        </div>
    </div>
</body>
</html>

提示:尊重用户的无障碍偏好,使用 @media (prefers-reduced-motion: reduce) 为需要减少动画的用户提供替代方案。

四、浏览器兼容性

特性 Chrome Firefox Safari Edge IE
@keyframes43+16+9+12+10+
animation43+16+9+12+10+
animation-fill-mode43+16+9+12+10+
animation-play-state43+16+9+12+10+

五、注意事项与最佳实践

注意事项

  • 性能优先:动画属性优先使用 transformopacity,避免触发重排

  • will-change:对频繁动画的元素添加 will-change: transform 提示浏览器优化

  • 动画暂停:使用 animation-play-state: paused 暂停动画而非销毁重建

  • prefers-reduced-motion:尊重用户的无障碍偏好设置

  • 关键帧顺序0% 可省略(使用元素初始样式),但 100% 不可省略

最佳实践

  • 命名规范:动画名称使用语义化命名,如 fadeInslideInLeft

  • 时长控制:UI 反馈动画 0.2-0.5s,装饰动画 1-3s,避免过长

  • 循环动画:无限循环动画应尽量简单,避免消耗过多性能

  • 动画延迟:利用 animation-delay 创建错落效果

  • GPU加速:对动画元素使用 transform: translateZ(0) 开启GPU加速

六、代码规范示例

不推荐的写法

代码示例

/* 不推荐:动画触发重排 */
@keyframes bad {
    0% { width: 100px; height: 100px; }
    100% { width: 200px; height: 200px; }
}

/* 不推荐:过长的动画时长 */
.box { animation: fadeIn 5s ease; }

/* 不推荐:忽略无障碍偏好 */
.box { animation: spin 1s linear infinite; }

推荐的写法

代码示例

/* 推荐:使用transform替代 */
@keyframes good {
    0% { transform: scale(1); }
    100% { transform: scale(2); }
}

/* 推荐:合理的动画时长 */
.box { animation: fadeIn 0.3s ease; }

/* 推荐:尊重用户偏好 */
.box { animation: spin 1s linear infinite; }
@media (prefers-reduced-motion: reduce) {
    .box { animation: none; }
}

七、常见问题与解决方案

常见问题

动画结束后元素回到初始状态怎么办?

animation-fill-mode 默认为 none。解决方案:设置 animation-fill-mode: forwards 保持结束状态。

动画卡顿不流畅怎么办?

动画属性触发了重排(如 width、height、top、left)。解决方案:改用 transform 和 opacity,添加 will-change 属性。

多个动画冲突怎么办?

多个动画修改同一属性导致冲突。解决方案:确保不同动画修改不同属性,或使用 transform 的组合函数。

如何创建加载动画?

常见的加载动画有旋转圈(border-top-color + spin动画)、弹跳点(scale + delay)、滑动条(translateX),都使用 @keyframes 定义动画,配合 animation 属性控制播放。

如何实现打字机效果?

结合 width 动画和 steps() 时序函数,配合闪烁光标动画:animation: typewriter 3s steps(20) forwards, blink 0.7s step-end infinite。

八、总结

CSS animation 配合 @keyframes 是创建复杂动画的强大工具,通过 namedurationtiming-functiondelayiteration-countdirectionfill-modeplay-state 八个子属性精确控制动画行为。在实际开发中,应优先使用 transformopacity 保证性能,使用 fill-mode: forwards 保持结束状态,尊重 prefers-reduced-motion 用户偏好。

核心原则

优先GPU加速、合理时长、尊重用户偏好、语义化命名。好的CSS动画能提升用户体验,但过度使用会造成视觉疲劳和性能问题。

标签: CSS动画 @keyframes animation 加载动画 打字机效果 CSS关键帧 prefers-reduced-motion

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: CSS集成:CSS过渡详解 - transition属性与交互效果完整指南 下一篇: CSS变换教程-transform属性2D三维变换详解

poll相关推荐