CSS——变换、过度与动画

巧妙的使用变换、过度与动画可以让页面设计更有趣、更吸引人,同时还能提高可用性和感知性能。

文章目录

一,变换

通过修改坐标空间,CSS变换可以改变受影响内容的形状和位置------在平面和 3D 空间中的旋转、倾斜、缩放和平移,而不会破坏正常的文档流。

CSS2D Transform表示2D变换,目前获得了各主流浏览器的支持,但是CSS3D Transform支持程度不是很完善,仅能够在部分浏览器中获得支持。

在 CSS(和大部分的计算机图形学)中,原点 (0, 0) 在元素的左上角。每个点都使用数学上的向量符号 (x,y) 来描述。

(一)2D变换

1,定义旋转

rotate() 函数能够旋转指定的元素对象,接收一个角度参数值用来指定旋转的幅度。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>2d旋转</title>
    <style>
        div {
            display: flex;
            flex-wrap: wrap;
            margin: 40px;
        }
    </style>
</head>
<body>

<div>
    <div style="width: 50px; height: 50px; background-color: #f4f5f0">0</div>
    <div style="width: 50px; height: 50px; background-color: red; transform: rotate(45deg);">1</div>
    <div style="width: 50px; height: 50px; background-color: green; transform: rotate(90deg);">2</div>
    <div style="width: 50px; height: 50px; background-color: blue; transform: rotate(180deg);">3</div>
    <div style="width: 50px; height: 50px; background-color: purple; transform: rotate(-45deg);">6</div>
    <div style="width: 50px; height: 50px; background-color: orange; transform: rotate(-90deg);">7</div>
    <div style="width: 50px; height: 50px; background-color: gray; transform: rotate(-180deg);">8</div>
</div>
</body>
</html>

2,定义缩放

scale() 函数能够缩放元素大小,接收两个参数,分别用来定义宽和高缩放比例。

  • 参数值可以是正数、负数和小数。正数值基于指定的宽度和高度将放大元素。负数值不会缩小元素,而是翻转元素(如文字被反转),然后再缩放元素。使用小于1的小数(如0.5)可以缩小元素。
  • 如果第2个参数省略,则第2个参数等于第1个参数值。
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>缩放</title>

    <style>
        div {
            display: flex;
            flex-wrap: wrap;
            margin: 40px;
        }
    </style>
</head>
<body>
<div>
    <div style="width: 50px; height: 50px; background-color: #f4f5f0">0</div>
    <div style="width: 50px; height: 50px; background-color: red; transform: scale(0.5);">1</div>
    <div style="width: 50px; height: 50px; background-color: red; transform: scale(1.5);">2</div>
    <div style="width: 50px; height: 50px; background-color: green; transform: scale(2);">3</div>
    <div style="width: 50px; height: 50px; background-color: blue; transform: scale(-0.5);">4</div>
    <div style="width: 50px; height: 50px; background-color: blue; transform: scale(-1.5);">5</div>
    <div style="width: 50px; height: 50px; background-color: purple; transform: scale(-2);">6</div>
</div>
</body>
</html>

3,定义移动

translate() 函数能够重新定位元素的坐标,该函数包含两个参数值,分别用来定义 x 轴和 y 轴坐标

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>2d移动</title>

    <style>
        div {
            /*display: flex;*/
            /*flex-wrap: wrap;*/
            margin: 10px;
        }

        .container {
            width: 50px;
            height: 50px;
            background-color: #f4f5f0;
        }

        .item {
            width: 25px;
            height: 25px;
            position: relative;
        }
    </style>
</head>
<body>
<div>
    <div class="container">
        <div class="item"
             style="transform: translate(25px, 0);background-color: red;">1
        </div>
    </div>
    <div class="container">
        <div class="item"
             style="transform: translate(0, 25px); background-color: green;">2
        </div>
    </div>
    <div class="container">
        <div class="item"
             style="transform: translate(-25px, 0); background-color: blue;">3
        </div>
    </div>
    <div class="container">
        <div class="item"
             style="transform: translate(0, -25px);  background-color: purple;">4
        </div>
    </div>
    <div class="container">
        <div class="item"
             style="transform: translate(25px, 25px);background-color: orange;">5
        </div>
    </div>
    <div class="container">
        <div class="item"
             style="transform: translate(-25px, -25px); background-color: gray;">6
        </div>
    </div>
</div>
</body>
</html>

4,定义倾斜

skew()函数能够让元素倾斜显示,该函数包含两个参数值,分别用来定义x轴和y轴坐标倾斜的角。

  • 如果省略了第2个参数,则第2个参数值默认值为0
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>2d倾斜</title>
    <style>
        .container {
            width: 100px;
            height: 100px;
            background-color: #9a9999;
            margin: 20px;
        }
    </style>
</head>
<body>
<div class="container">
    <div class="item" style="transform: skew(30deg);background-color: #ff4040;">2d倾斜</div>
</div>
<div class="container">
    <div class="item" style="transform: skew(0, 20deg);background-color: #62fc43;">2d倾斜</div>
</div>
<div class="container">
    <div class="item" style="transform: skew(30deg, 20deg);background-color: #00c1f9;">2d倾斜</div>
</div>
</div>
</div>
</body>
</html>

5,定义矩阵

matrix() 是矩阵函数,调用该函数可以非常灵活的实现各种变换效果,如倾斜(skew)、缩放(scale)、 旋转(rotate)以及位移(translate)。语法格式如下:

html 复制代码
matrix(<number>, <number>, <number>, <number>, <number>, <number>)
  • 第1参数控制X轴缩放,第2个参数控制X轴倾斜,第3个参数控制Y轴倾斜,第4个参数
    控制Y轴缩放,第5个参数控制X轴移动,第6个参数控制Y轴移动。
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>2d矩阵</title>
    <style>
        .container {
            width: 100px;
            height: 100px;
            background-color: #9a9999;
            margin: 20px;
        }
    </style>
</head>
<body>
<div class="container">
    <div class="item" style="transform: matrix(1, 0, 0, 1, 0, 0);background-color: #ff4040;">2d矩阵</div>
</div>
<div class="container">
    <div class="item" style="transform: matrix(1, 0, 0, 1, 20, 20);background-color: #62fc43;">2d矩阵</div>
</div>
<div class="container">
    <div class="item" style="transform: matrix(1, 0, 0, 1, 40, 40);background-color: #00c1f9;">2d矩阵</div>
</div>
</body>
</html>

6,定义变换原点

CSS变换的原点默认为对象的中心点 ,如果要改变这个中心点,可以使用transform-origin属性进行定义。基本语法如下所示:

html 复制代码
transform-origin:[ [ <percentage> | <length> | left | center | right ] [ <percentage>|<length> | top | center | bottom ] ? ] | [ [ left | center | right ] | [ [ top | center | bottom]]
  • transform-origin属性的初始值为50% 50%,它适用于块状元素和内联元素。
  • transform-origin接收两个参数,它们可以是百分比、em、px等具体的值,也可以是left、center、right,或者top、middle、bottom等描述性关键字。
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>变换原点</title>
    <style>
        .container {
            width: 120px;
            height: 120px;
            background-color: #9a9999;
            margin: 20px 0 20px 100px;
            position: relative;
        }

        .item {
            width: 100px;
            height: 100px;
            position: relative;
            color: white;
            font-size: 12px;
            display: flex;
            align-items: center;
            justify-content: center;
            text-align: center;
        }

        /* 🔵 中心点样式 */
        .center-point {
            width: 6px;
            height: 6px;
            background-color: yellow;
            border-radius: 50%;
            position: absolute;
            transform: translate(-50%, -50%);
        }

        /* 🟥 以左上角为中心 */
        .item-1 {
            background-color: #ff4040;
            transform-origin: left top;
            transform: rotate(45deg);
        }
        .item-1 .center-point {
            top: 0;
            left: 0;
        }

        /* 🟩 以中心为中心 */
        .item-2 {
            background-color: #62fc43;
            transform-origin: center center;
            transform: rotate(45deg);
        }
        .item-2 .center-point {
            top: 50%;
            left: 50%;
        }

        /* 🟦 以左侧 20%、底部为中心 */
        .item-3 {
            background-color: #00c1f9;
            transform-origin: 20% bottom;
            transform: rotate(45deg);
        }
        .item-3 .center-point {
            top: 100%;
            left: 20%;
        }
    </style>
</head>
<body>

<div class="container">
    <div class="item item-1">
        以左上角为原点,旋转45度
        <div class="center-point"></div>
    </div>
</div>

<div class="container">
    <div class="item item-2">
        以中心为原点,旋转45度
        <div class="center-point"></div>
    </div>
</div>

<div class="container">
    <div class="item item-3">
        以距离左边20%、底部为原点,旋转45度
        <div class="center-point"></div>
    </div>
</div>

</body>
</html>

7,例子:卡片悬浮

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hover Card</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #f5f5f5;
        }

        .card {
            width: 250px;
            height: 150px;
            background: white;
            border-radius: 12px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
            transition: transform 0.3s ease, box-shadow 0.3s ease;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 20px;
            font-weight: bold;
        }

        .card:hover {
            transform: translateY(-10px); /* 悬停时上移 */
            box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3); /* 增加阴影,增强浮动感 */
        }
    </style>
</head>
<body>
    <div class="card">Hover Me!</div>
</body>
</html>

(二)3D变换

暂时放一放。

二,过度

CSS3使用 transition 属性定义过渡动画。CSS 过渡提供了一种在更改 CSS 属性时控制动画速度的方法。其可以让属性变化成为一个持续一段时间的,而不是立即生效的过程。比如,将一个元素的颜色从白色改为黑色,通常这个改变是立即生效的,使用 CSS 过渡后该元素的颜色将按照一定的曲线速率从白色变化为黑色。这个过程可以自定义。

(一)设置过渡属性

transition-property属性用来定义过渡动画的CSS属性名称:

html 复制代码
transition-property:none | all | [ <IDENT> ] [','<IDENT> ] *
  • none:表示没有元素
  • all:默认值,表示针对所有元素,包括:befbre和:after伪元素
  • IDENT:指定CSS属性列表。几乎所有色彩、大小或位置等相关的CSS属性,包括许多新添加的CSS3属性,都可以应用过渡,如CSS3变换中的放大、缩小、旋转、斜切、渐变等。
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>transition-property属性定义过渡动画的CSS属性名称</title>

    <style>
        div {
            margin: 10px auto;
            height: 80px;
            background: red;
            border-radius: 12px;
            box-shadow: 2px 2px 2px #999;
        }

        div:hover {
            background-color: blue;
            transition-property: background-color;
            -webkit-transition-property: background-color;
            -moz-transition-property: background-color;
            -o-transition-property: background-color;
        }
    </style>
</head>
<body>
<div></div>
</body>
</html>

(二)设置过渡时间

transition-duration属性用来定义转换动画的时间长度:

html 复制代码
transition-duration:<time> [, <time>]*;
  • 初始值为0,适用于所有元素,以及:before和:after伪元素。在默认情况下,动画过渡时间为0秒,所以当指定元素动画时,会看不到过渡的过程,直接看到结果。
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>设置过渡时间</title>

    <style>
        div {
            margin: 10px auto;
            height: 80px;
            background: red;
            border-radius: 12px;
            box-shadow: 2px 2px 2px #999;
        }

        div:hover {
            /* 设置过渡时间 */
            transition-duration: 2s;
            -webkit-transition-duration: 2s;
            -moz-transition-duration: 2s;
            -o-transition-duration: 2s;
            background: blue;
        }
    </style>
</head>
<body>
<div></div>
<!--<div style="margin: 10px auto; height: 80px; background: red; border-radius: 12px; box-shadow: 2px 2px 2px #999;" onmouseover="this.style.transitionDuration='2s';this.style.webkitTransitionDuration='2s';this.style.mozTransitionDuration='2s';this.style.oTransitionDuration='2s';this.style.background='blue';" onmouseout="this.style.transitionDuration='1s';this.style.webkitTransitionDuration='1s';this.style.mozTransitionDuration='1s';this.style.oTransitionDuration='1s';this.style.background='red';"></div>-->
</body>
</html>

(三)设置延迟时间

transition-delay属性用来定义开启过渡动画的延迟时间:

css 复制代码
transition-delay:<time> [, <time>]*;
  • 初始值为0,适用于所有元素,以及:before和:after伪元素。
  • 设置时间可以为正整数、负整数和零。非零的时候必须设置单位是s (秒)或者ms (毫秒)。为正数的时候,过渡的动作会延迟触发。可以设置负的延迟值,这会让过渡效果从中途开始,好像效果已经运行了0.2秒才开始一样。
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>设置延迟时间</title>

    <style>
        div {
            margin: 10px auto;
            height: 80px;
            background-color: blue;
            border-radius: 12px;
            box-shadow: 2px 2px 2px #999;
        }

        .box1 {
            /* 过渡持续时间为1秒,延迟0.5秒后开始 */
            transition-property: background-color;
            transition-duration: 1s;
            transition-delay: 0.5s;
        }

        .box1:hover {
            background-color: red;
        }

        .box2:hover {
            /* 过渡持续时间为1秒,延迟0.5秒后开始 */
            transition-property: background-color;
            transition-duration: 1s;
            transition-delay: 0.5s;
            background-color: red;
        }
    </style>
</head>
<body>
<div class="box1"></div>
<div class="box2"></div>
</body>
</html>

(四)设置过渡动画类型

transition-timing-fiinction属性用来定义过渡动画的类型:

html 复制代码
transition-timing-function:ease | linear | ease-in | ease-out | ease-in-out | cubicbezier(<number>, <number>, <number>, <number>) [, ease | linear | ease-in |ease-out | ease-in-out | cubic-bezier(<number>, <number>,<number>, <number>)]*
  • ease:平滑过渡,等同于cubic-bezier(0.25, 0.1, 0.25,1.0)函数,即立方贝塞尔。
  • linear:线性过渡,等同于 cubic-bezier(0.0, 0.0, 1.0, 1.0)函数。
  • ease-in:由慢到快,等同于 cubic-bezier(0.42, 0, 1.0, 1.0)函数。
  • ease-out:由快到慢,等同于 cubic-bezier(0, 0, 0.58, 1.0)函数。
  • ease-in-out:由慢到快再到慢,等同于 cubic-bezier(0.42, 0, 0.58, 1.0)函数。
  • cubic-bezier:特殊的立方贝塞尔曲线效果。

具体的动画曲线:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>所有的过渡动画类型</title>

    <style>
        div {
            margin: 10px;
            /*margin: 10px auto;*/
            width: 180px;
            background-color: blue;
            /*text-align: center;*/
        }

        .ease:hover {
            width: 100vh;
            transition-property: width;
            transition-duration: 1s;
            transition-timing-function: ease;
        }

        .ease-in:hover {
            width: 100vh;
            transition-property: width;
            transition-duration: 1s;
            transition-timing-function: ease-in;
        }

        .ease-out:hover {
            width: 100vh;
            transition-property: width;
            transition-duration: 1s;
            transition-timing-function: ease-out;
        }

        .ease-in-out:hover {
            width: 100vh;
            transition-property: width;
            transition-duration: 1s;
            transition-timing-function: ease-in-out;
        }

        .linear:hover {
            width: 100vh;
            transition-property: width;
            transition-duration: 1s;
            transition-timing-function: linear;
        }

        .step-start:hover {
            width: 100vh;
            transition-property: width;
            transition-duration: 1s;
            transition-timing-function: step-start;
        }

        .step-end:hover {
            width: 100vh;
            transition-property: width;
            transition-duration: 1s;
            transition-timing-function: step-end;
        }

        .cubic-bezier:hover {
            width: 100vh;
            transition-property: width;
            transition-duration: 1s;
            /* 0.1表示起始速度,0.7表示中间速度,1.0表示结束速度,0.1表示结束速度 */
            transition-timing-function: cubic-bezier(0.1, 0.7, 1.0, 0.1);
        }
    </style>
</head>
<body>
<div class="ease">ease</div>
<div class="ease-in">ease-in</div>
<div class="ease-out">ease-out</div>
<div class="ease-in-out">ease-in-out</div>
<div class="linear">linear</div>
<div class="step-start">step-start</div>
<div class="step-end">step-end</div>
<div class="cubic-bezier">cubic-bezier</div>
</body>
</html>

(五)设置触发方式

CSS3动画一般通过鼠标事件或状态定义动画,如CSS伪类和Javascript事件。

动态伪类 作用元素 说明
:hover 所有元素 鼠标指针悬停在元素上时的状态
:active 所有元素 元素被激活(如鼠标按下)时的状态
:focus 可聚焦元素(如输入框、按钮) 元素获得焦点时的状态
:link 锚点元素 (<a>) 未被访问的链接的状态
:visited 锚点元素 (<a>) 已被访问的链接的状态

Javascript 事件包括 click、focus、mousemove、mouseover、mouseout 等。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>设置触发方式</title>

    <style>
        div {
            margin: 10px auto;
            height: 80px;
            background: red;
            border-radius: 12px;
            box-shadow: 2px 2px 2px #999;
        }

        .hover:hover {
            background-color: blue;
            transition-property: background-color;
            -webkit-transition-property: background-color;
            -moz-transition-property: background-color;
            -o-transition-property: background-color;
        }

        .active:active {
            background-color: blue;
            transition-property: background-color;
            -webkit-transition-property: background-color;
            -moz-transition-property: background-color;
            -o-transition-property: background-color;
        }

        .focus:focus {
            background-color: blue;
            transition-property: background-color;
            -webkit-transition-property: background-color;
            -moz-transition-property: background-color;
            -o-transition-property: background-color;
        }

        a.link:link {
            background-color: blue;
            transition-property: background-color;
            -webkit-transition-property: background-color;
            -moz-transition-property: background-color;
            -o-transition-property: background-color;
        }

        a.visited:visited {
            background-color: blue;
            transition-property: background-color;
            -webkit-transition-property: background-color;
            -moz-transition-property: background-color;
            -o-transition-property: background-color;
        }
    </style>
</head>
<body>

<div class="hover">hover</div>
<div class="active">active</div>
<label>
    <input class="focus" type="text" value="focus">
</label>

<a class="link" href="#">link</a>
<a class="visited" href="#">visited</a>
</body>
</html>

(六)简写

css允许简写来组合transition-property、transition-duration、transition-delay、transition-timing-function。

css 复制代码
// background-color 属性会在 1 秒延迟后开始过渡,持续 2 秒,并使用 ease-in-out 时间曲线。opacity 会在 0.3 秒内以默认的 ease 曲线过渡。
transition: background-color 2s ease-in-out 1s, opacity 0.3s;

(六)例子:打开弹窗

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>展开的对话框</title>

    <style>
        .control {
            position: fixed;
            /* 固定在页面的右下角 */
            right: 10px;
            bottom: 10px;

            border-radius: 50%;
            width: 30px;
            height: 30px;
            background-color: #ff4040;
            color: white;
            font-size: 20px;
            font-weight: bolder;
            border: none;
            /* 添加阴影 */
            box-shadow: 2px 2px 2px #999;
            z-index: 1000;
            transition: all 0.3s ease;
        }

        .control:hover {
            background-color: #ff0000;
            cursor: pointer;
            transform: scale(1.1);
        }

        .control:active {
            background-color: #ff0000;
            /* 添加阴影 */
            box-shadow: 1px 1px 1px #f4f5f0;
            transform: scale(0.95);
        }

        /* 提示框样式 */
        .tooltip {
            position: absolute;
            background-color: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 5px 10px;
            border-radius: 4px;
            font-size: 12px;
            bottom: 40px;
            right: 0;
            white-space: nowrap;
            pointer-events: none; /* 使鼠标事件穿透提示框 */
            opacity: 0;
            transform: translateY(10px);
            transition: opacity 0.3s ease, transform 0.3s ease;
        }

        /* 按钮容器,用于定位提示框 */
        .button {
            position: fixed;
            right: 10px;
            bottom: 10px;
        }

        /* 显示提示框 */
        .open:hover + .tooltip {
            opacity: 1;
            transform: translateY(0);
        }

        #dialog {
            position: fixed;
            /* 固定在页面的右下角 */
            right: 10px;
            bottom: 50px;
            width: 300px;
            height: 400px;
            overflow: hidden;
            background-color: #f4f5f0;
            border-radius: 4px;
            opacity: 1;

            /* 添加过渡效果 */
            transition: all 0.5s ease;
            transform-origin: bottom right;
        }

        /* 对话框关闭状态 */
        #dialog.hidden {
            transform: scale(0.1);
            opacity: 0;
            visibility: hidden;
        }

        #content {
            width: calc(100% - 20px);
            height: calc(100% - 40px);
            min-width: calc(100% - 20px);
            min-height: calc(100% - 40px);
            max-width: calc(100% - 20px);
            max-height: calc(100% - 40px);
            border: none;
            resize: both;
            margin: 10px;
            transition: opacity 0.3s ease;
        }

        /* 键盘快捷键提示 */
        .shortcut-hint {
            position: absolute;
            bottom: 30px;
            right: 10px;
            font-size: 11px;
            color: #666;
            opacity: 0.8;
        }

        #submit {
            border-radius: 4px;
            width: 100%;
            background-color: #ff4040;
            color: white;
            font-weight: bolder;
            border: none;
            /* 添加阴影 */
            box-shadow: 2px 2px 2px #999;
            /* 按钮位于底部 */
            position: sticky;
            bottom: 2px;
            transition: background-color 0.3s ease, box-shadow 0.3s ease;
        }

        #submit:hover {
            background-color: #ff0000;
        }

        #submit:active {
            background-color: #f65353;
            /* 添加阴影 */
            box-shadow: 1px 1px 1px #f4f5f0;
        }
    </style>
</head>
<body>
<div id="dialog" class="hidden">
    <label for="content">
        <textarea id="content" placeholder="请输入内容"></textarea>
    </label>
    <div class="shortcut-hint">提示: 按 Ctrl+Enter 亦可发送</div>
    <br/>
    <button id="submit">发送</button>
</div>
<div class="button">
    <button class="control open">+</button>
    <div class="tooltip">联系客服</div>
    <button class="control close">×</button>
</div>

<script>
    let btnOpen = document.querySelector('.open');
    let btnClose = document.querySelector('.close');
    let dialog = document.getElementById('dialog');
    let content = document.getElementById('content');
    let submitBtn = document.getElementById('submit');

    // 初始状态设置
    btnClose.style.display = 'none';

    btnOpen.onclick = function () {
        // 显示对话框并添加过渡动画
        dialog.classList.remove('hidden');

        // 切换按钮显示
        btnClose.style.display = 'block';
        btnOpen.style.display = 'none';

        // 聚焦到文本框
        setTimeout(() => {
            content.focus();
        }, 500);
    };

    btnClose.onclick = function () {
        // 隐藏对话框并添加过渡动画
        dialog.classList.add('hidden');

        // 切换按钮显示,但需要等待过渡完成
        setTimeout(() => {
            btnOpen.style.display = 'block';
            btnClose.style.display = 'none';
            // 清空文本框
            content.value = '';
        }, 300);
    }

    // 增强的提交按钮交互
    submitBtn.onclick = function (e) {
        // 将消息内容输出到控制台
        console.log(content.value);
    }

    // 添加键盘快捷键支持 - Ctrl+Enter
    content.addEventListener('keydown', function (e) {
        // 检测是否同时按下Ctrl键和Enter键
        if (e.ctrlKey && e.key === 'Enter') {
            e.preventDefault(); // 阻止默认行为(通常是换行)
            console.log(content.value);
        }
    });
</script>
</body>
</html>

三,动画

CSS3使用animation属性定义帧动画。

Animations 功能与 Transition 功能相同,都是通过改变元素的属性值来实现动画效果的。它们的区别在于:使用 Transitions 功能时只能通过指定属性的开始值与结束值,然后在这两个属性值之间进行平滑过渡的方式来实

现动画效果,因此不能实现比较复杂的动画效果;而 Animations 则通过定义多个关键帧以及定义每个关键帧中元素的属性值来实现更为复杂的动画效果。

(一)设置关键帧

CSS3使用 @keyframes 定义关键帧:

css 复制代码
@keyframes animation-name (
	keyframes-selector (
		css-styles;
	}
}

@keyframes animation-name {
  from {
    /* 初始状态 */
  }
  to {
    /* 结束状态 */
  }
}

@keyframes animation-name {
  0% {
    /* 初始状态 */
  }
  50% {
    /* 中间状态 */
  }
  100% {
    /* 结束状态 */
  }
}
  • animationname:定义动画的名称。
  • keyframes-selector:定义帧动画时长的百分比,合法的值包括0~100%,from(等价于0%)、to (等价于100%)。
  • css-styles:表示一个或多个合法的CSS样式属性。
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <style>
        .box {
            width: 100px;
            height: 100px;
            background-color: red;
            animation: move 2s ease-in-out infinite;
        }

        @keyframes move {
            0% {
                transform: translateX(0);
            }
            50% {
                transform: translateX(200px);
            }
            100% {
                transform: translateX(0);
            }
        }
    </style>
</head>
<body>
<div class="box"></div>
</body>
</html>

(二)设置动画属性

1,定义动画名称

使用animation-name属性可以定义CSS动画的名称:

css 复制代码
animation-timing-function: ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier(n,n,n,n) | step-start | step-end | steps(n, start|end) | initial | inherit;
  • keyframeName:指定要绑定到选择器的关键帧的名称
  • none:指定没有关键帧
  • initial:设置为默认值
  • inherit:从父元素继承
  • 当指定多个动画时,它们会并行运行,而不是顺序执行。
html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS Animation-Name 属性详解</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }

        h1, h2 {
            color: #333;
        }

        .container {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            margin: 30px 0;
        }

        .demo-box {
            width: 100px;
            height: 100px;
            background-color: #3498db;
            display: flex;
            justify-content: center;
            align-items: center;
            color: white;
            font-weight: bold;
            border-radius: 5px;
        }

        .example-section {
            background-color: white;
            border-radius: 8px;
            padding: 20px;
            margin-bottom: 30px;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
        }

        code {
            background-color: #f0f0f0;
            padding: 2px 5px;
            border-radius: 3px;
            font-family: monospace;
        }

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

        .bounce-animation {
            animation-name: bounce;
            animation-duration: 2s;
            animation-iteration-count: infinite;
        }

        /* 颜色变化动画 */
        @keyframes colorChange {
            0% {
                background-color: #3498db;
            }
            25% {
                background-color: #e74c3c;
            }
            50% {
                background-color: #2ecc71;
            }
            75% {
                background-color: #f39c12;
            }
            100% {
                background-color: #3498db;
            }
        }

        .color-animation {
            animation-name: colorChange;
            animation-duration: 4s;
            animation-iteration-count: infinite;
        }

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

        .multiple-animations {
            animation-name: bounce, colorChange;
            animation-duration: 2s, 4s;
            animation-iteration-count: infinite;
        }

        /* 带前缀的动画 */
        .rotate-animation {
            animation-name: rotate;
            animation-duration: 3s;
            animation-timing-function: linear;
            animation-iteration-count: infinite;
        }

        /* 动画混合示例 */
        .complex-animation {
            animation-name: bounce, rotate, colorChange;
            animation-duration: 2s, 3s, 4s;
            animation-iteration-count: infinite;
        }

        /* 演示none值 */
        .no-animation {
            animation-name: none;
            background-color: #95a5a6;
        }

        /* 演示动画控制 */
        .controlled-animation {
            animation-name: bounce;
            animation-duration: 2s;
            animation-iteration-count: infinite;
            animation-play-state: paused;
        }

        .controlled-animation:hover {
            animation-play-state: running;
        }

        /* 按钮样式 */
        button {
            padding: 8px 15px;
            background-color: #3498db;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin-top: 10px;
        }

        button:hover {
            background-color: #2980b9;
        }
    </style>
</head>
<body>
<h1>CSS animation-name 属性详解</h1>

<div class="example-section">
    <h2>1. 基本用法</h2>
    <p>这个例子展示了一个简单的弹跳动画,使用 <code>animation-name: bounce</code>:</p>
    <div class="container">
        <div class="demo-box bounce-animation">弹跳</div>
    </div>
    <pre><code>
.bounce-animation {
    animation-name: bounce;
    animation-duration: 2s;
    animation-iteration-count: infinite;
}

@keyframes bounce {
    0% { transform: translateY(0); }
    50% { transform: translateY(-30px); }
    100% { transform: translateY(0); }
}
        </code></pre>
</div>

<div class="example-section">
    <h2>2. 颜色变化动画</h2>
    <p>这个例子展示了颜色过渡动画,使用 <code>animation-name: colorChange</code>:</p>
    <div class="container">
        <div class="demo-box color-animation">颜色变化</div>
    </div>
    <pre><code>
.color-animation {
    animation-name: colorChange;
    animation-duration: 4s;
    animation-iteration-count: infinite;
}

@keyframes colorChange {
    0% { background-color: #3498db; }
    25% { background-color: #e74c3c; }
    50% { background-color: #2ecc71; }
    75% { background-color: #f39c12; }
    100% { background-color: #3498db; }
}
        </code></pre>
</div>

<div class="example-section">
    <h2>3. 多个动画名称</h2>
    <p>一个元素可以同时应用多个动画,用逗号分隔:</p>
    <div class="container">
        <div class="demo-box multiple-animations">多动画</div>
    </div>
    <pre><code>
.multiple-animations {
    animation-name: bounce, colorChange;
    animation-duration: 2s, 4s;
    animation-iteration-count: infinite;
}
        </code></pre>
</div>

<div class="example-section">
    <h2>4. 旋转动画</h2>
    <p>这个例子展示了旋转动画:</p>
    <div class="container">
        <div class="demo-box rotate-animation">旋转</div>
    </div>
    <pre><code>
.rotate-animation {
    animation-name: rotate;
    animation-duration: 3s;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
}

@keyframes rotate {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}
        </code></pre>
</div>

<div class="example-section">
    <h2>5. 复杂动画组合</h2>
    <p>可以组合多个动画创建复杂效果:</p>
    <div class="container">
        <div class="demo-box complex-animation">复杂动画</div>
    </div>
    <pre><code>
.complex-animation {
    animation-name: bounce, rotate, colorChange;
    animation-duration: 2s, 3s, 4s;
    animation-iteration-count: infinite;
}
        </code></pre>
</div>

<div class="example-section">
    <h2>6. 无动画 (none)</h2>
    <p>使用 <code>animation-name: none</code> 可以移除所有动画:</p>
    <div class="container">
        <div class="demo-box no-animation">无动画</div>
    </div>
    <pre><code>
.no-animation {
    animation-name: none;
}
        </code></pre>
</div>

<div class="example-section">
    <h2>7. 交互控制</h2>
    <p>鼠标悬停时启动动画:</p>
    <div class="container">
        <div class="demo-box controlled-animation">悬停启动</div>
    </div>
    <pre><code>
.controlled-animation {
    animation-name: bounce;
    animation-duration: 2s;
    animation-iteration-count: infinite;
    animation-play-state: paused;
}

.controlled-animation:hover {
    animation-play-state: running;
}
        </code></pre>
</div>

<div class="example-section">
    <h2>animation-name 的重要特性</h2>
    <ul>
        <li>如果指定的关键帧不存在,不会有动画效果</li>
        <li>如果提供多个动画名称,它们将同时运行</li>
        <li>动画名称区分大小写</li>
        <li>可以通过设置为 <code>none</code> 来移除所有动画</li>
        <li>通常与其他动画属性一起使用,如 <code>animation-duration</code></li>
        <li>可以通过简写属性 <code>animation</code> 一并设置所有动画属性</li>
    </ul>
</div>

<div class="example-section">
    <h2>与其他动画属性的配合</h2>
    <p>完整的动画控制需要与以下属性配合:</p>
    <ul>
        <li><code>animation-duration</code>: 动画完成一个周期所需时间</li>
        <li><code>animation-timing-function</code>: 动画如何进行(缓动函数)</li>
        <li><code>animation-delay</code>: 动画开始前的延迟时间</li>
        <li><code>animation-iteration-count</code>: 动画播放次数</li>
        <li><code>animation-direction</code>: 动画播放方向</li>
        <li><code>animation-fill-mode</code>: 动画执行前后如何应用样式</li>
        <li><code>animation-play-state</code>: 动画运行或暂停</li>
    </ul>
    <p>所有这些属性可以通过 <code>animation</code> 简写属性一次性设置。</p>
</div>
</body>
</html>

2,定义动画时间

使用animation-duration属性可以定义CSS动画播放时间:

css 复制代码
animation-duration: time;
  • 在默认情况下该属性值为0,这意味着动画周期是直接的,即不会有动画。当值为负值时,则被视为0。
  • time: 指定动画完成一个周期所需的时间,可以使用以下单位:秒:如 2s(2秒);毫秒:如 500ms(500毫秒,即0.5秒)
  • initial: 将此属性设置为其默认值
  • inherit: 从父元素继承此属性
html 复制代码
在这里插入代码片

3,定义动画类型

使用animation-timing-function属性可以定义CSS动画类型:

css 复制代码
animation-timing-function:ease | linear | ease-in | ease-out | ease-in-out | cubicbezier(<number>,<number>, number>, <number>) [, ease | linear |ease-in | ease-out | ease-in-out | cubic-bezier(<number>, <number>, <number>, <number>)]*
html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS Animation-Timing-Function 属性详解</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            max-width: 900px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }

        h1, h2, h3 {
            color: #333;
        }

        .demo-container {
            margin: 20px 0;
            padding: 20px;
            background-color: white;
            border-radius: 8px;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
            position: relative;
            overflow: hidden;
        }

        .track {
            height: 50px;
            background-color: #f0f0f0;
            border-radius: 25px;
            position: relative;
            margin: 20px 0;
        }

        .ball {
            width: 40px;
            height: 40px;
            background-color: #3498db;
            border-radius: 50%;
            position: absolute;
            top: 5px;
            left: 5px;
            display: flex;
            justify-content: center;
            align-items: center;
            color: white;
            font-weight: bold;
            font-size: 12px;
        }

        .btn-container {
            display: flex;
            gap: 10px;
            margin-top: 10px;
        }

        button {
            padding: 8px 15px;
            background-color: #3498db;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }

        button:hover {
            background-color: #2980b9;
        }

        .code-block {
            background-color: #f0f0f0;
            padding: 15px;
            border-radius: 5px;
            margin: 10px 0;
            overflow-x: auto;
            font-family: monospace;
        }

        /* 定义动画 */
        @keyframes moveRight {
            from {
                left: 5px;
            }
            to {
                left: calc(100% - 45px);
            }
        }

        /* 不同的timing-function演示 */
        .timing-ease .ball {
            animation: moveRight 3s ease infinite alternate;
        }

        .timing-linear .ball {
            animation: moveRight 3s linear infinite alternate;
        }

        .timing-ease-in .ball {
            animation: moveRight 3s ease-in infinite alternate;
        }

        .timing-ease-out .ball {
            animation: moveRight 3s ease-out infinite alternate;
        }

        .timing-ease-in-out .ball {
            animation: moveRight 3s ease-in-out infinite alternate;
        }

        .timing-cubic-bezier .ball {
            animation: moveRight 3s cubic-bezier(0.68, -0.55, 0.27, 1.55) infinite alternate;
        }

        /* 阶梯函数演示 */
        .timing-steps-5 .ball {
            animation: moveRight 3s steps(5, end) infinite alternate;
        }

        .timing-step-start .ball {
            animation: moveRight 3s step-start infinite alternate;
        }

        .timing-step-end .ball {
            animation: moveRight 3s step-end infinite alternate;
        }

        /* 复杂演示 */
        .bounce-box {
            width: 60px;
            height: 60px;
            background-color: #e74c3c;
            border-radius: 10px;
            margin: 20px auto;
        }

        @keyframes bounce {
            0%, 20%, 50%, 80%, 100% {
                transform: translateY(0);
            }
            40% {
                transform: translateY(-30px);
            }
            60% {
                transform: translateY(-15px);
            }
        }

        .bounce-demo .bounce-box {
            animation: bounce 2s infinite;
        }

        /* 自定义曲线演示 */
        .custom-curve-container {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
        }

        .custom-curve-box {
            width: calc(50% - 10px);
            padding: 10px;
            background-color: #f8f9fa;
            border-radius: 5px;
        }

        @keyframes slideIn {
            from {
                transform: translateX(-100%);
                opacity: 0;
            }
            to {
                transform: translateX(0);
                opacity: 1;
            }
        }

        .elastic-box {
            width: 100px;
            height: 50px;
            background-color: #9b59b6;
            border-radius: 5px;
            color: white;
            display: flex;
            justify-content: center;
            align-items: center;
            animation: slideIn 2s cubic-bezier(0.68, -0.6, 0.32, 1.6) infinite alternate;
        }

        .bounce-out-box {
            width: 100px;
            height: 50px;
            background-color: #2ecc71;
            border-radius: 5px;
            color: white;
            display: flex;
            justify-content: center;
            align-items: center;
            animation: slideIn 2s cubic-bezier(0.19, 1, 0.22, 1) infinite alternate;
        }
    </style>
</head>
<body>
<h1>CSS animation-timing-function 属性详解</h1>

<p>动画时间函数控制动画在每个周期中的速度曲线。以下是各种常用值的实际演示:</p>

<div class="demo-container">
    <h2>基本时间函数</h2>

    <div class="track timing-ease">
        <div class="ball">ease</div>
    </div>

    <div class="track timing-linear">
        <div class="ball">linear</div>
    </div>

    <div class="track timing-ease-in">
        <div class="ball">ease-in</div>
    </div>

    <div class="track timing-ease-out">
        <div class="ball">ease-out</div>
    </div>

    <div class="track timing-ease-in-out">
        <div class="ball">ease-in-out</div>
    </div>

    <div class="code-block">
        /* 默认值,缓慢开始,然后加速,最后减速 */
        animation-timing-function: ease;

        /* 匀速运动 */
        animation-timing-function: linear;

        /* 缓慢开始,然后加速 */
        animation-timing-function: ease-in;

        /* 快速开始,然后减速 */
        animation-timing-function: ease-out;

        /* 缓慢开始,然后加速,最后减速 */
        animation-timing-function: ease-in-out;
    </div>
</div>

<div class="demo-container">
    <h2>Cubic Bezier 函数</h2>
    <p>通过自定义贝塞尔曲线创建更精确的时间函数:</p>

    <div class="track timing-cubic-bezier">
        <div class="ball">弹跳效果</div>
    </div>

    <div class="code-block">
        /* 创建弹跳效果的贝塞尔曲线 */
        animation-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55);
    </div>

    <p>cubic-bezier 函数接受四个参数,表示贝塞尔曲线的控制点 P1(x1, y1) 和 P2(x2, y2)。</p>
</div>

<div class="demo-container">
    <h2>Steps 函数</h2>
    <p>创建帧动画效果,使动画在固定数量的步骤中完成:</p>

    <div class="track timing-steps-5">
        <div class="ball">steps(5)</div>
    </div>

    <div class="track timing-step-start">
        <div class="ball">step-start</div>
    </div>

    <div class="track timing-step-end">
        <div class="ball">step-end</div>
    </div>

    <div class="code-block">
        /* 将动画分为5个步骤 */
        animation-timing-function: steps(5, end);

        /* 立即跳至关键帧末尾(等同于 steps(1, start)) */
        animation-timing-function: step-start;

        /* 立即跳至关键帧开始(等同于 steps(1, end)) */
        animation-timing-function: step-end;
    </div>
</div>

<div class="demo-container">
    <h2>实际应用示例</h2>

    <h3>1. 弹跳效果</h3>
    <div class="bounce-demo">
        <div class="bounce-box"></div>
    </div>

    <div class="code-block">
        @keyframes bounce {
        0%, 20%, 50%, 80%, 100% { transform: translateY(0); }
        40% { transform: translateY(-30px); }
        60% { transform: translateY(-15px); }
        }

        .bounce-box {
        animation: bounce 2s infinite;
        }
    </div>

    <h3>2. 自定义曲线效果</h3>
    <div class="custom-curve-container">
        <div class="custom-curve-box">
            <h4>弹性效果</h4>
            <div class="elastic-box">弹性效果</div>
            <div class="code-block">
                animation: slideIn 2s cubic-bezier(0.68, -0.6, 0.32, 1.6) infinite alternate;
            </div>
        </div>

        <div class="custom-curve-box">
            <h4>缓出效果</h4>
            <div class="bounce-out-box">缓出效果</div>
            <div class="code-block">
                animation: slideIn 2s cubic-bezier(0.19, 1, 0.22, 1) infinite alternate;
            </div>
        </div>
    </div>
</div>

<div class="demo-container">
    <h2>timing-function 使用技巧</h2>

    <h3>1. 适用场景</h3>
    <ul>
        <li><strong>ease</strong>: 适用于大多数自然运动,如页面元素的过渡</li>
        <li><strong>linear</strong>: 适用于匀速运动,如进度条、时钟</li>
        <li><strong>ease-in</strong>: 适用于离开视图的元素,如淡出效果</li>
        <li><strong>ease-out</strong>: 适用于进入视图的元素,如淡入效果</li>
        <li><strong>ease-in-out</strong>: 适用于进入后又离开的过渡</li>
        <li><strong>cubic-bezier</strong>: 适用于需要精确控制的动画效果</li>
        <li><strong>steps</strong>: 适用于帧动画、精灵图动画</li>
    </ul>

    <h3>2. 性能考虑</h3>
    <p>在复杂动画中,尽量使用 transform 和 opacity 属性,因为它们可以利用硬件加速,提高性能。</p>

    <h3>3. 可访问性</h3>
    <p>考虑使用 <code>prefers-reduced-motion</code> 媒体查询来尊重用户的动画偏好:</p>

    <div class="code-block">
        @media (prefers-reduced-motion: reduce) {
        .animated-element {
        animation: none;
        transition: none;
        }
        }
    </div>
</div>
</body>
</html>

4,定义延迟时间

使用animation-delay属性可以定义CSS动画延迟播放的时间:

css 复制代码
animation-delay:<time> [, <time>]*;
  • 该属性允许一个动画开始执行一段时间后才被应用。当动画延迟时间为0,即默认动画延迟时间,则意味着动画将尽快执行,否则该值指定将延迟执行的时间。

5,定义播放次数

使用animation-iteration-count属性定义CSS动画的播放次数:

css 复制代码
animation-iteration-count:infinite | <number> [, infinite | <number>]*;
  • 默认值为1,这意味着动画将播放从开始到结束一次。infinite表示无限次,即CSS动画永远重复。 如果取值为非整数,将导致动画结束一个周期的一部分。如果取值为负值,则将导致在交替周期内反向播放动画。
html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>animation-iteration-count 示例</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            padding: 20px;
        }

        .container {
            display: flex;
            flex-direction: column;
            gap: 30px;
            max-width: 800px;
            margin: 0 auto;
        }

        .box {
            width: 100px;
            height: 100px;
            background-color: #3498db;
            border-radius: 8px;
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-weight: bold;
        }

        /* 动画定义 */
        @keyframes bounce {
            0%, 100% {
                transform: translateY(0);
            }
            50% {
                transform: translateY(-30px);
            }
        }

        /* 播放1次(默认值) */
        .once {
            animation: bounce 1s ease-in-out;
            animation-iteration-count: 1;
        }

        /* 播放3次 */
        .three-times {
            animation: bounce 1s ease-in-out;
            animation-iteration-count: 3;
        }

        /* 播放1.5次(会在中间状态停止) */
        .one-and-half {
            animation: bounce 1s ease-in-out;
            animation-iteration-count: 1.5;
        }

        /* 无限循环 */
        .infinite {
            animation: bounce 1s ease-in-out;
            animation-iteration-count: infinite;
        }

        .description {
            margin-top: 10px;
            padding: 10px;
            background-color: #f8f9fa;
            border-radius: 5px;
        }
    </style>
</head>
<body>
<div class="container">
    <h1>animation-iteration-count 示例</h1>

    <div>
        <div class="box once">1次</div>
        <div class="description">animation-iteration-count: 1; (默认值)</div>
    </div>

    <div>
        <div class="box three-times">3次</div>
        <div class="description">animation-iteration-count: 3;</div>
    </div>

    <div>
        <div class="box one-and-half">1.5次</div>
        <div class="description">animation-iteration-count: 1.5; (会在中间状态停止)</div>
    </div>

    <div>
        <div class="box infinite">无限</div>
        <div class="description">animation-iteration-count: infinite;</div>
    </div>
</div>
</body>
</html>

6,. 定义播放方向

使用animation-direction属性定义CSS动画的播放方向:

css 复制代码
animation-direction:normal | alternate [, normal [ alternate]*;
  • normal (默认值):动画正常播放(从 0% 到 100%)
  • reverse:动画反向播放(从 100% 到 0%)
  • alternate:动画先正向播放,然后反向播放,交替进行
  • alternate-reverse:动画先反向播放,然后正向播放,交替进行
html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS animation-direction 示例</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: 20px;
        }

        .container {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            gap: 30px;
            margin-top: 20px;
        }

        .box {
            width: 100px;
            height: 100px;
            background-color: #3498db;
            border-radius: 10px;
            display: flex;
            justify-content: center;
            align-items: center;
            color: white;
            font-weight: bold;
            margin-bottom: 40px;
        }

        .title {
            margin-top: 10px;
            text-align: center;
            font-size: 14px;
        }

        /* 定义关键帧动画 */
        @keyframes slide {
            from {
                transform: translateX(0);
            }
            to {
                transform: translateX(200px);
            }
        }

        /* 正常方向动画 */
        .normal {
            animation: slide 2s infinite;
            animation-direction: normal;
        }

        /* 反向动画 */
        .reverse {
            animation: slide 2s infinite;
            animation-direction: reverse;
        }

        /* 交替动画 */
        .alternate {
            animation: slide 2s infinite;
            animation-direction: alternate;
        }

        /* 反向交替动画 */
        .alternate-reverse {
            animation: slide 2s infinite;
            animation-direction: alternate-reverse;
        }
    </style>
</head>
<body>
<h1>CSS animation-direction 示例</h1>

<div class="container">
    <div>
        <div class="box normal">normal</div>
        <div class="title">正常方向 (默认)</div>
    </div>

    <div>
        <div class="box reverse">reverse</div>
        <div class="title">反向播放</div>
    </div>

    <div>
        <div class="box alternate">alternate</div>
        <div class="title">交替播放</div>
    </div>

    <div>
        <div class="box alternate-reverse">alternate-reverse</div>
        <div class="title">反向交替播放</div>
    </div>
</div>

<p>观察每个方块的运动方向差异:</p>
<ul>
    <li><strong>normal</strong>: 从左到右循环</li>
    <li><strong>reverse</strong>: 从右到左循环</li>
    <li><strong>alternate</strong>: 从左到右再到左交替</li>
    <li><strong>alternate-reverse</strong>: 从右到左再到右交替</li>
</ul>
</body>
</html>

7,定义播放状态

使用animation-play-state属性定义动画正在运行,还是暂停:

css 复制代码
animation-play-state: paused|running;
  • 初始值为running。其中paused定义动画己暂停,running定义动画正在播放。

8,定义播放外状态

使用animation-fill-mode属性定义动画外状态:

css 复制代码
animation-fill-mode: none | forwards | backwards | both [ , none | forwards | backwards | both ]*
  • none:不设置对象动画之外的状态。
  • forwards:设置对象状态为动画结束时的状态。
  • backwards:设置对象状态为动画开始时的状态。
  • both:设置对象状态为动画结束或开始的状态。

(三)例子:logo动画

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>个人博客Logo动画</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #f0f0f0;
            font-family: Arial, sans-serif;
        }

        .logo-container {
            width: 250px;
            height: 250px;
            position: relative;
            perspective: 1000px;
        }

        .logo {
            position: absolute;
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 120px;
            font-weight: bold;
            color: white;
            border-radius: 50%;
            background-color: #3498db;
            /* 指定动画风格,preserve-3d 表示保持3D效果 */
            transform-style: preserve-3d;
            /* 指定动画名称,对应下面的关键帧动画 */
            animation-name: logoAnimation;
            /* 指定动画持续时间 */
            animation-duration: 4s;
            /* 指定动画时间函数,cubic-bezier 表示贝塞尔曲线 */
            animation-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55);
            /* 指定动画延迟时间,infinite 表示无限循环 */
            animation-iteration-count: infinite;
            /* 指定动画播放方向,alternate 表示来回播放 */
            animation-direction: alternate;
            /* 指定动画填充模式,both 表示动画结束后保持最后一帧 */
            animation-fill-mode: both;
        }

        @keyframes logoAnimation {
            0% {
                /* 旋转角度、缩放比例、Y轴旋转角度 */
                transform: rotate(0deg) scale(0.7) rotateY(0deg);
                background-color: #3498db;
                /* 字母间距 */
                letter-spacing: -20px;
                /* 透明度,取值范围为0~1 */
                opacity: 0.6;
            }
            25% {
                transform: rotate(90deg) scale(1) rotateY(180deg);
                background-color: #2ecc71;
                letter-spacing: 5px;
                opacity: 1;
            }
            50% {
                transform: rotate(180deg) scale(1.2) rotateY(360deg);
                background-color: #e74c3c;
                letter-spacing: 10px;
                opacity: 0.8;
            }
            75% {
                transform: rotate(270deg) scale(1) rotateY(540deg);
                background-color: #f39c12;
                letter-spacing: 5px;
                opacity: 1;
            }
            100% {
                transform: rotate(360deg) scale(0.7) rotateY(720deg);
                background-color: #3498db;
                letter-spacing: -20px;
                opacity: 0.6;
            }
        }

        .logo-container:hover .logo {
            /* 暂停动画 */
            animation-play-state: paused;
        }
    </style>
</head>
<body>
<div class="logo-container">
    <div class="logo">H</div>
</div>
</body>
</html>
相关推荐
崔庆才丨静觅4 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60615 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了5 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅5 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅5 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅6 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment6 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅6 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊6 小时前
jwt介绍
前端
爱敲代码的小鱼6 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax