🌈 CSS 动画魔法:过渡、变换与动画

177 阅读7分钟

在正式探索动画之前,我们先来认识CSS中的两位“魔法助手”——过渡(Transition)和变换(Transform)。它们是实现网页元素动效的基石!✨

🚥 1 过渡(Transition)

1.1 它的作用

就像给变化加了“慢镜头”🎬!transition 能让元素属性的变化过程平滑过渡,而不是瞬间“闪现”。(比如按钮颜色渐变、大小变化)。

1.2 施展魔法的咒语(语法)

控制过渡效果的几个关键属性:

  1. transition-property: 指定哪些属性要过渡(默认 all 表示所有属性)。
  2. transition-duration: 必须设置! 过渡持续的时间(默认 0s 等于没效果)。
  3. transition-timing-function: 控制变化速度曲线(默认是 ease 先快后慢)。
  4. transition-delay: 变化开始前的等待时间(默认 0s)。

🧙‍♀️ 简洁咒语(简写):

transition: 属性名 持续时间 速度曲线 延迟时间;
/* 例如:让宽度在0.5秒内匀速变化 */
transition: width 0.5s linear;

🌀 2 变换(Transform)

2.1 它的作用

transform 是元素的“变形大师”🧙!它能直接改变元素的形状或位置(比如旋转、缩放、移动、倾斜)。默认是瞬间变形的,想让它变“丝滑”?需要配合 AnimationTransition 一起使用。

变形有两种舞台

  1. 2D 变换: 在**平面舞台(X 轴和 Y 轴)**上表演(旋转、缩放、移动)。
  2. 3D 变换: 在**立体舞台(X、Y、Z 轴)**上表演,效果更炫酷!

2.2 核心变形术

2.2.1 移动术: translate

transform: translate(水平移动, 垂直移动); /* 2D移动 */
transform: translateX(值); /* 只动X轴 */
transform: translateY(值); /* 只动Y轴 */
transform: translateZ(值); /* 3D: 沿Z轴移动 (近大远小感) */
transform: translate3d(x, y, z); /* 3D自由移动 */

🔑 要点笔记

  • 移动时不会挤开周围其他元素(布局友好!👍)。
  • 使用百分比 50% 时,是相对于元素自身大小来计算的。
  • 对行内元素(如 <span>)无效。

💡 妙用

  • 做酷炫动效。
  • 让元素完美居中transform: translate(-50%, -50%); + top: 50%; left: 50%;

2.2.2 旋转术: rotate

transform: rotate(45deg); /* 2D: 顺时针转45度 */
transform: rotateX(45deg); /* 3D: 绕X轴转 */
transform: rotateY(45deg); /* 3D: 绕Y轴转 */
transform: rotateZ(45deg); /* 3D: 绕Z轴转 (类似2D旋转) */
transform: rotate3d(x, y, z, 角度); /* 自定义旋转轴 */

🔑 要点笔记

  • 角度单位是 deg (度)。
  • 正数顺时针转🔁,负数逆时针转🔄。
  • 默认围绕元素中心点旋转。

2.2.3 缩放术: scale

transform: scale(水平缩放倍数, 垂直缩放倍数); /* 2D缩放 */
transform: scaleX(倍数); /* 只缩放宽度 */
transform: scaleY(倍数); /* 只缩放高度 */
transform: scaleZ(倍数); /* 3D: 沿Z轴缩放 (需配合其他3D属性) */
transform: scale3d(x倍数, y倍数, z倍数); /* 3D缩放 */

🔑 要点笔记

  • >1 放大,0~1 缩小,<0 会镜像翻转🔍。
  • scale(2) 等于 scale(2, 2),宽高都放大2倍。
  • 缩放不影响其他元素的布局(布局友好!👍)。
  • 默认从中心点开始缩放。

2.3 🎯 设置变形中心点 (transform-origin)

想改变旋转/缩放的支点?用它!

/* 2D 变形 */
transform-origin: x轴位置 y轴位置; /* 例如: left top, 50% 100%, 20px 30px */
/* 3D 变形 (增加Z轴) */
transform-origin: x轴位置 y轴位置 z轴距离; /* Z轴只能用长度(px等),正值向外 */

2.4 🔮 3D 魔法空间

想让 3D 变换效果更真实?需要这两个重要设置:

2.4.1 perspective:营造景深(透视感)

  • 作用: 模拟眼睛👁️‍🗨️到3D 舞台的距离,产生“近大远小”的立体感。值越小,3D 感越强!
  • 设置位置: 加在3D 元素的父容器上。
.parent {
  perspective: 800px; /* 试试调整这个值感受效果变化 */
}

2.4.2 transform-style: preserve-3d:开启真实3D 空间

  • 作用: 告诉浏览器,子元素要保留在真实的3D 空间里(有前后层次,能互相遮挡)。
  • 设置位置: 加在3D 元素的直接父容器上。
.parent {
  perspective: 800px;
  transform-style: preserve-3d; /* 关键!让子元素在3D空间排布 */
}

✨ 3 动画(Animation)

动画 (animation) 是 CSS3 的超级大招!🎆 它比过渡更强大,能定义多个关键帧精确控制每一步变化、自动循环播放,实现复杂炫酷的效果。

3.1 📜 编写动画剧本 (@keyframes)

定义动画在不同时间点的状态:

@keyframes 你的动画名字 {
  0% { /* 开始时的样式 */ }
  50% { /* 中间点的样式 */ }
  100% { /* 结束时的样式 */ }
}
/* 或者简单的从...到... */
@keyframes 简单动画 {
  from { /* 起始状态 */ }
  to { /* 结束状态 */ }
}

3.2 🎬 开启动画 (animation)

把写好的剧本“播放”在元素上:

.element {
  animation-name: 你的动画名字; /* 必须的 */
  animation-duration: 3s; /* 必须的,动画时长 */
}
/* 简洁写法 */
.element {
  animation: 动画名字 时长 速度曲线 延迟 播放次数 方向 结束状态;
}

3.3 🎛️ 动画控制台(常用属性)

属性名作用描述常用值
animation-name指定要使用的 @keyframes 动画名称 (必须)你定义的动画名
animation-duration动画完成一次需要的时间 (必须)2s, 500ms
animation-timing-function动画速度变化曲线ease (默认), linear, ease-in, ease-out, ease-in-out, steps(4)
animation-delay动画开始前的等待时间1s, 0.5s (默认 0s)
animation-iteration-count动画播放次数1 (默认), 3, infinite (无限循环)
animation-direction动画播放方向normal (正向), reverse (反向), alternate (正反交替)
animation-play-state暂停或播放动画running (播放, 默认), paused (暂停)
animation-fill-mode动画结束后元素的样式状态forwards (保持结束帧), backwards (回到起始帧), both
animation (简写)上面属性的简写 (除了 play-state)name duration timing-function delay iteration-count direction fill-mode

3.3.1 速度曲线 (animation-timing-function) 小贴士

  • steps(5): 让动画分成5步“跳”着完成,适合做帧动画效果。
  • linear: 匀速运动。

🧙‍♂️ 简写示例:

.box {
  animation: bounce 1s ease-in-out 0.2s infinite alternate;
  /* 解读: 使用'bounce'动画, 1秒完成, 缓入缓出, 延迟0.2秒开始, 无限循环, 每次方向交替 */
}

🎪 4 魔法秀场(案例)

4.1 🧊 案例1:3D 翻转盒子导航

效果:鼠标放上去,盒子像魔方一样翻转到另一面。

<style>
        .box { /* 注意:多个元素用class,不要用id */
            position: relative;
            width: 50px;
            height: 50px;
            margin: 50% 0;
            left: 20%;
            float: left;
            transform-style: preserve-3d; /* 开启3D空间 */
            transition: transform 0.35s; /* 给翻转加过渡 */
            cursor: pointer;
        }
        .box:hover {
            transform: rotateX(90deg); /* 鼠标悬停时绕X轴旋转90度 */
        }
        .front, .bottom {
            position: absolute;
            color: #fff;
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .front {
            background: red;
            transform: translateZ(25px); /* 向前移动形成正面 */
        }
        .bottom {
            background: blue;
            /* 先向下移动,再绕X轴旋转-90度(使其朝下),形成底面 */
            transform: translateY(25px) rotateX(-90deg);
        }
</style>
<body>
    <div class="box">
        <div class="front">首页</div>
        <div class="bottom">详情</div>
    </div>
    <div class="box">
        <div class="front">产品</div>
        <div class="bottom">购买</div>
    </div>
    <div class="box">
        <div class="front">关于</div>
        <div class="bottom">团队</div>
    </div>
    <div class="box">
        <div class="front">博客</div>
        <div class="bottom">文章</div>
    </div>
    <div class="box">
        <div class="front">联系</div>
        <div class="bottom">表单</div>
    </div>
</body>

4.2 🎠 案例2:3D 旋转木马轮播图

效果:图片像旋转木马一样围绕中心旋转,鼠标放上去暂停。

<style>
        body {
            perspective: 1000px; /* 给整个页面加透视 */
        }
        #carousel {
            position: relative;
            width: 300px;
            height: 200px;
            margin: 100px auto;
            transform-style: preserve-3d; /* 关键!子元素保持3D空间关系 */
            animation: carousel-rotate 10s infinite linear; /* 自动旋转动画 */
        }
        #carousel:hover {
            animation-play-state: paused; /* 鼠标悬停暂停旋转 */
        }
        @keyframes carousel-rotate {
            from { transform: rotateY(0deg); }
            to { transform: rotateY(360deg); } /* 绕Y轴旋转一圈 */
        }
        #carousel .panel {
            position: absolute;
            top: 0;
            width: 100%;
            height: 100%;
            color: #fff;
            background: rgba(0, 0, 0, 0.7); /* 半透明背景 */
            transition: transform 0.35s; /* 给缩放加过渡 */
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 2rem;
        }
        #carousel .panel:hover {
            transform: scale(1.1); /* 鼠标悬停放大 */
            background: rgba(0, 0, 0, 0.9); /* 悬停加深背景 */
        }
        /* 将6个面板均匀分布在旋转木马圆周上 */
        #carousel .panel:nth-child(1) { transform: translateZ(400px); }
        #carousel .panel:nth-child(2) { transform: rotateY(60deg) translateZ(400px); }
        #carousel .panel:nth-child(3) { transform: rotateY(120deg) translateZ(400px); }
        #carousel .panel:nth-child(4) { transform: rotateY(180deg) translateZ(400px); }
        #carousel .panel:nth-child(5) { transform: rotateY(240deg) translateZ(400px); }
        #carousel .panel:nth-child(6) { transform: rotateY(300deg) translateZ(400px); }
</style>
<body>
    <div id="carousel">
        <div class="panel">1</div>
        <div class="panel">2</div>
        <div class="panel">3</div>
        <div class="panel">4</div>
        <div class="panel">5</div>
        <div class="panel">6</div>
    </div>
</body>

📚 5 宝藏库推荐

想做出超酷炫的动画,但觉得手写太复杂?试试这些强大的工具库吧!

  1. Animate.css: 超全的预定义 CSS 动画库,开箱即用!
    animate.style/

  2. React Spring (for Web): 基于物理弹簧原理的动画库,效果超自然流畅!(尤其适合 React 项目)
    www.react-spring.dev/