CSS Transitions & Animations & Transforms 9

86 阅读17分钟

一、 CSS 过渡 (Transitions)

过渡允许 CSS 属性值在一段时间内平滑地从一个状态变化到另一个状态(例如,当 :hover 或 :focus 状态激活时)。

  1. transition-property

    • 作用: 指定要应用过渡效果的 CSS 属性名称。

    • 值:

      • none: 没有属性会进行过渡。
      • all: (默认值) 所有可动画的属性都将进行过渡。
      • : 一个或多个 CSS 属性的名称,用逗号分隔。如 width, color, background-color, transform。
    • 示例: transition-property: opacity, transform;

  2. transition-duration

    • 作用: 指定过渡效果完成所需的时间。

    • 值:

    • 示例: transition-duration: 0.3s;

  3. transition-timing-function

    • 作用: 指定过渡期间的速度曲线(加速度)。

    • 值:

      • 预定义关键字:

        • 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))。
        • step-start: 等同于 steps(1, start),立即跳到结束状态。
        • step-end: 等同于 steps(1, end),保持在开始状态直到时间结束,然后立即跳到结束状态。
      • 函数:

        • steps([, ]): 分步过渡。 是步数, 可选值为 jump-start (或 start) 或 jump-end (或 end, 默认)。如 steps(4, end)。
        • cubic-bezier(, , , ): 定义自定义三次贝塞尔曲线,四个参数分别代表 P1 和 P2 控制点的 x, y 坐标。如 cubic-bezier(0.1, 0.7, 1.0, 0.1)。
    • 示例: transition-timing-function: ease-in-out;

  4. transition-delay

    • 作用: 指定过渡效果开始前的延迟时间。

    • 值:

    • 示例: transition-delay: 0.1s;

  5. transition (简写属性)

    • 作用: 在一个声明中设置所有四个过渡属性。

    • 语法: 可以按任意顺序列出最多四个值,对应 transition-property, transition-duration, transition-timing-function, transition-delay。

      • 如果只提供一个时间值,它会被解析为 transition-duration。
      • 如果提供两个时间值,第一个是 duration,第二个是 delay。
      • 可以为多个属性分别设置过渡,用逗号分隔。
    • 重要: 简写会重置未指定的属性为其默认值。

    • 示例:

      • transition: background-color 0.5s ease-out;
      • transition: opacity 0.3s linear 0.1s; (属性 时长 缓动函数 延迟)
      • transition: all 0.4s cubic-bezier(.17,.67,.83,.67);
      • transition: width 0.2s ease-in, height 0.4s ease-out 0.1s; (两个属性的不同过渡)

二、 CSS 动画 (Animations)

动画允许你创建更复杂的、基于关键帧的动画序列,可以自动播放、重复,并有更多控制选项。

  1. @keyframes 规则

    • 作用: 定义动画的名称和关键帧(动画过程中的特定时间点及其样式)。

    • 语法:

            @keyframes <animation-name> {
        <keyframe-selector> {
          /* CSS 样式声明 */
        }
        <keyframe-selector> {
          /* CSS 样式声明 */
        }
        /* ... */
      }
          
      
      • : 你为动画定义的名称,供 animation-name 属性引用。

      • : 定义关键帧的时间点。可以是:

        • from: 等同于 0%。
        • to: 等同于 100%。
        • : 从 0% 到 100% 的百分比。
    • 示例:

            @keyframes slide-in {
        from { transform: translateX(-100%); opacity: 0; }
        to   { transform: translateX(0); opacity: 1; }
      }
      @keyframes pulse {
        0% { transform: scale(1); }
        50% { transform: scale(1.1); }
        100% { transform: scale(1); }
      }
          
      
  2. animation-name

    • 作用: 指定要应用到元素的 @keyframes 动画的名称。

    • 值:

      • none: (默认值) 不应用任何动画。
      • : 一个或多个 @keyframes 规则定义的名称,用逗号分隔。如 slide-in, pulse, fade-out。
    • 示例: animation-name: pulse;

  3. animation-duration

    • 作用: 指定动画完成一个周期所需的时间。

    • 值:

    • 示例: animation-duration: 2s;

  4. animation-timing-function

    • 作用: 指定动画在每个周期内的速度曲线。
    • 值: 与 transition-timing-function 的值相同 (ease, linear, ease-in, ease-out, ease-in-out, steps(), cubic-bezier() 等)。默认值为 ease。
    • 示例: animation-timing-function: linear;
  5. animation-delay

    • 作用: 指定动画效果开始前的延迟时间。

    • 值:

    • 示例: animation-delay: 0.5s;

  6. animation-iteration-count

    • 作用: 指定动画应该播放的次数。

    • 值:

      • : 播放的具体次数。默认值为 1。
      • infinite: 无限次重复播放。
    • 示例: animation-iteration-count: infinite;

  7. animation-direction

    • 作用: 指定动画在每个周期结束后是否反向播放。

    • 值:

      • normal: (默认值) 每个周期都向前播放 (从 from 到 to)。
      • reverse: 每个周期都反向播放 (从 to 到 from)。
      • alternate: 奇数次向前播放,偶数次反向播放。
      • alternate-reverse: 奇数次反向播放,偶数次向前播放。
    • 示例: animation-direction: alternate;

  8. animation-fill-mode

    • 作用: 指定动画在执行之前和之后(即不在播放期间时)如何将样式应用于其目标。

    • 值:

      • none: (默认值) 动画结束后,元素样式返回到其原始状态。在 animation-delay 期间,应用原始样式。
      • forwards: 动画结束后,元素将保持动画最后一个关键帧计算的样式。
      • backwards: 在 animation-delay 期间,元素将应用动画第一个关键帧计算的样式。
      • both: 同时应用 forwards 和 backwards 的规则。
    • 示例: animation-fill-mode: forwards;

  9. animation-play-state

    • 作用: 指定动画是正在运行还是暂停。通常用于通过 JavaScript 控制动画。

    • 值:

      • running: (默认值) 动画正在播放。
      • paused: 动画已暂停。
    • 示例: animation-play-state: paused;

  10. animation (简写属性)

    • 作用: 在一个声明中设置一个或多个动画属性。

    • 语法: 可以包含 animation-name, animation-duration, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, animation-fill-mode, animation-play-state 的值。顺序有一定要求(特别是时间值,duration 在前,delay 在后)。

      • 可以为多个动画设置属性,用逗号分隔。
    • 重要: 简写会重置未指定的属性为其默认值。

    • 示例:

      • animation: 3s ease-in 1s infinite reverse both paused slidein;
      • animation: pulse 2s linear infinite, fadeout 1s ease-out forwards; (两个动画)

三、 CSS 变换 (Transforms)

变换允许你在不影响文档流的情况下,对元素进行移动、旋转、缩放或倾斜。变换通常发生在渲染过程的后期,利用 GPU 加速,性能较好,非常适合与过渡和动画结合使用。

  1. transform

    • 作用: 应用一个或多个 2D 或 3D 变换函数到元素。

    • 值:

      • none: (默认值) 不应用任何变换。

      • +: 一个或多个变换函数,用空格分隔。顺序很重要! 变换是依次应用的。

        • 2D 变换函数:

          • translate([, ]): 沿 X 轴和 Y 轴移动。单位可以是 px, % (相对于自身尺寸) 等。如 translate(50px, 20%)。
          • translateX(): 仅沿 X 轴移动。
          • translateY(): 仅沿 Y 轴移动。
          • scale([, ]): 沿 X 轴和 Y 轴缩放。1 是原始大小,1.5 是放大 50%,0.5 是缩小 50%。如 scale(1.2), scale(1, 0.8)。
          • scaleX(): 仅沿 X 轴缩放。
          • scaleY(): 仅沿 Y 轴缩放。
          • rotate(): 在 2D 平面内旋转。单位是 deg (度), rad (弧度), grad (百分度), turn (圈)。如 rotate(45deg)。
          • skew([, ]): 沿 X 轴和 Y 轴倾斜。单位是 deg, rad 等。如 skew(10deg, 5deg)。
          • skewX(): 仅沿 X 轴倾斜。
          • skewY(): 仅沿 Y 轴倾斜。
          • matrix({6}): 使用 2x3 变换矩阵直接定义 2D 变换。
        • 3D 变换函数:

          • translate3d(, , ): 沿 X, Y, Z 轴移动。
          • translateZ(): 沿 Z 轴移动(需要 perspective 才能看出效果)。
          • scale3d(, , ): 沿 X, Y, Z 轴缩放。
          • scaleZ(): 仅沿 Z 轴缩放。
          • rotate3d(, , , ): 围绕一个 3D 向量 [x, y, z] 旋转指定角度。
          • rotateX(): 围绕 X 轴旋转。
          • rotateY(): 围绕 Y 轴旋转。
          • rotateZ(): 围绕 Z 轴旋转 (效果同 rotate())。
          • perspective(): 为当前元素设置透视距离(不同于父元素上的 perspective 属性)。
          • matrix3d({16}): 使用 4x4 变换矩阵直接定义 3D 变换。
    • 示例: transform: translateX(100px) rotate(30deg) scale(0.8);

  2. transform-origin

    • 作用: 设置变换操作(旋转、缩放、倾斜)的原点。默认是元素的中心点 (50% 50% 0)。

    • 值: 可以是 1、2 或 3 个值,分别代表 X、Y、Z 轴的原点位置。

      • 关键字: left, center, right, top, bottom。
      • 长度/百分比: 或 。
    • 示例: transform-origin: top left;, transform-origin: 50% 100%;, transform-origin: 0 0 -50px; (包含 Z 轴)

  3. transform-style (应用于 3D 变换元素的父元素)

    • 作用: 指定元素的子元素如何在 3D 空间中呈现。

    • 值:

      • flat: (默认值) 子元素不保留其 3D 位置,会被扁平化到父元素的平面。
      • preserve-3d: 子元素保留其 3D 位置。创建嵌套的 3D 场景时必须设置。
    • 示例: transform-style: preserve-3d;

  4. perspective (应用于 3D 变换元素的父元素)

    • 作用: 为其 3D 定位的子元素设置透视效果的强度。它定义了观察者与 Z=0 平面之间的距离。

    • 值:

      • none: (默认值) 无透视效果。
      • : 一个正长度值,表示距离。值越小,透视效果越强烈(失真越大)。如 800px, 1000px。
    • 示例: perspective: 1000px;

  5. perspective-origin (应用于 3D 变换元素的父元素)

    • 作用: 设置 perspective 属性的消失点 (vanishing point) 的位置。默认是父元素的中心 (50% 50%)。
    • 值: 与 transform-origin 的 X, Y 值语法相同(关键字、长度、百分比)。
    • 示例: perspective-origin: top right;, perspective-origin: 50% 0;
  6. backface-visibility

    • 作用: 定义当元素的背面面向观察者时是否可见。

    • 值:

      • visible: (默认值) 背面可见(通常是正面的镜像)。
      • hidden: 背面不可见(元素变为透明)。
    • 示例: backface-visibility: hidden; (常用于创建翻转卡片效果)

  7. transform-box (较新属性)

    • 作用: 定义 transform 和 transform-origin 属性所参照的布局框。主要用于 SVG 元素。

    • 值:

      • content-box: (HTML 默认,但不适用于 SVG)
      • border-box: (HTML 默认)
      • fill-box: 使用对象的填充框 (SVG 常用)。
      • stroke-box: 使用对象的描边框 (SVG 常用)。
      • view-box: 使用最近的 SVG 视口 (SVG 常用,通常是默认值)。
    • 示例: transform-box: fill-box;

案例 1 transitions

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS 过渡 (Transitions) 示例</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>

    <h1>CSS 过渡 (Transitions) 演示</h1>

    <div class="container">
        <h2>鼠标悬停看效果</h2>

        <!-- 示例 1: 基本过渡 -->
        <button class="btn btn-basic">基础过渡</button>
        <p>悬停时,背景色和文字颜色平滑过渡。</p>

        <!-- 示例 2: 过渡多个属性,不同时长和延迟 -->
        <button class="btn btn-multi">多属性过渡</button>
        <p>悬停时,背景色快速过渡,大小(通过 transform: scale)稍慢过渡并有延迟。</p>

        <!-- 示例 3: 使用不同的 timing-function -->
        <button class="btn btn-timing ease-in">Ease-In</button>
        <button class="btn btn-timing linear">Linear</button>
        <button class="btn btn-timing ease-out">Ease-Out</button>
        <button class="btn btn-timing cubic">Cubic Bezier</button>
        <p>悬停时,观察不同速度曲线的效果 (translateX)。</p>

        <!-- 示例 4: 分步过渡 (Steps) -->
        <button class="btn btn-steps">分步过渡</button>
        <p>悬停时,背景色分 4 步变化。</p>

    </div>

</body>
</html>
 body {
    font-family: sans-serif;
    padding: 20px;
    background-color: #f0f0f0;
    text-align: center; /* 让按钮居中显示 */
}

h1 {
    color: #333;
    margin-bottom: 30px;
}
h2 {
    color: #555;
    margin-bottom: 20px;
}

.container {
    background-color: #fff;
    padding: 30px;
    border-radius: 8px;
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
    margin-bottom: 30px;
}

.container p {
    color: #666;
    margin-top: 15px;
    font-size: 0.9em;
}

/* 按钮基础样式 */
.btn {
    display: inline-block; /* 使按钮可以并排,且能设置宽高 */
    padding: 12px 25px;
    margin: 10px;
    border: none;
    border-radius: 5px;
    font-size: 16px;
    cursor: pointer;
    outline: none; /* 移除默认的点击轮廓 */
    color: white; /* 默认文字颜色 */
    background-color: steelblue; /* 默认背景色 */
}

/* --- 示例 1: 基本过渡 --- */
.btn-basic {
    /* 定义要过渡的属性:背景色和文字颜色 */
    transition-property: background-color, color;
    /* 定义过渡的持续时间 */
    transition-duration: 0.4s; /* 400毫秒 */
    /* 定义过渡的速度曲线 (可选,默认是 ease) */
    /* transition-timing-function: ease; */
    /* 定义过渡的延迟 (可选,默认是 0s) */
    /* transition-delay: 0s; */

    /* 上面分开写的属性可以用简写代替: */
    /* transition: background-color 0.4s ease, color 0.4s ease; */
    /* 或者如果所有属性都用相同设置,可以更简洁: */
    /* transition: all 0.4s ease; */
}

/* 鼠标悬停时的状态 */
.btn-basic:hover {
    background-color: tomato; /* 目标背景色 */
    color: black; /* 目标文字颜色 */
}


/* --- 示例 2: 过渡多个属性,不同时长和延迟 --- */
.btn-multi {
    /* 为 background-color 和 transform 分别设置过渡 */
    transition: background-color 0.2s ease-out, /* 背景色:0.2秒,快速开始 */
                transform 0.5s ease-in-out 0.1s; /* 大小:0.5秒,缓入缓出,延迟0.1秒开始 */
    transform-origin: center; /* 确保缩放从中心开始 */
}

.btn-multi:hover {
    background-color: darkslateblue;
    transform: scale(1.1); /* 放大 10% */
}


/* --- 示例 3: 使用不同的 timing-function --- */
.btn-timing {
    background-color: mediumseagreen;
    transition-property: transform; /* 只过渡 transform 属性 */
    transition-duration: 0.8s;     /* 持续时间 */
}
.btn-timing:hover {
    transform: translateX(100px); /* 向右移动 100px */
}

/* 分别设置不同的 timing-function */
.btn-timing.ease-in {
    transition-timing-function: ease-in;
}
.btn-timing.linear {
    transition-timing-function: linear;
}
.btn-timing.ease-out {
    transition-timing-function: ease-out;
}
.btn-timing.cubic {
    /* 自定义贝塞尔曲线 */
    transition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55); /* 类似回弹效果 */
}


/* --- 示例 4: 分步过渡 (Steps) --- */
.btn-steps {
    background-color: orange;
    transition-property: background-color;
    transition-duration: 1s; /* 总时长 1 秒 */
    transition-timing-function: steps(4, end); /* 分成 4 步,在每步结束时跳变 */
    /* 试试 steps(4, start) 看看区别 */
}

.btn-steps:hover {
    background-color: purple;
}

案例 2 animations

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS 动画 (Animations) 示例</title>
    <link rel="stylesheet" href="1.css">
</head>
<body>

    <h1>CSS 动画 (Animations) 演示</h1>

    <div class="animation-container">
        <!-- 示例 1: 基本动画 (名称、时长) -->
        <div class="box box-basic">基础动画</div>
        <p>一个简单的从左侧滑入的动画,只播放一次。</p>

        <!-- 示例 2: 无限循环与速度曲线 (iteration-count, timing-function) -->
        <div class="box box-looping">无限循环 (linear)</div>
        <p>一个无限循环的脉冲效果,使用线性速度曲线。</p>

        <!-- 示例 3: 交替方向与填充模式 (direction, fill-mode) -->
        <div class="box box-direction-fill">交替变色 (forwards)</div>
        <p>背景色在红蓝之间来回交替变化,动画结束后保持在最终状态。</p>

        <!-- 示例 4: 延迟与播放次数 (delay, iteration-count) -->
        <div class="box box-delay-count">延迟播放 3 次</div>
        <p>动画延迟 1 秒后开始,并播放 3 次后停止。</p>

        <!-- 示例 5: 暂停动画 (play-state) -->
        <div class="box box-play-state">悬停暂停旋转</div>
        <p>一个无限旋转的动画,鼠标悬停时会暂停。</p>

        <!-- 示例 6: animation 简写属性 -->
        <div class="box box-shorthand">简写属性</div>
        <p>使用 `animation` 简写属性设置所有动画参数。</p>

         <!-- 示例 7: 应用多个动画 -->
        <div class="box box-multiple">多重动画</div>
        <p>同时应用滑动和缩放两种动画。</p>
    </div>

</body>
</html>
body {
    font-family: sans-serif;
    padding: 20px;
    background-color: #f4f4f4;
}

h1 {
    text-align: center;
    color: #333;
    margin-bottom: 40px;
}
p {
    color: #666;
    font-size: 0.9em;
    text-align: center;
    margin-top: 5px;
    margin-bottom: 30px; /* 增加示例间距 */
}

.animation-container {
    display: flex;
    flex-direction: column; /* 垂直排列示例 */
    align-items: center; /* 水平居中 */
}

/* 方块基础样式 */
.box {
    width: 100px;
    height: 100px;
    background-color: steelblue;
    color: white;
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 5px;
    margin-bottom: 10px; /* 方块和文字的间距 */
    font-size: 0.9em;
    text-align: center;
}

/* --- 定义关键帧动画 --- */

/* 动画 1: 从左滑入 */
@keyframes slide-in {
    from { /* 或者 0% */
        transform: translateX(-200px);
        opacity: 0;
    }
    to { /* 或者 100% */
        transform: translateX(0);
        opacity: 1;
    }
}

/* 动画 2: 脉冲(放大缩小) */
@keyframes pulse {
    0% {
        transform: scale(1);
        box-shadow: 0 0 0 0 rgba(0, 123, 255, 0.4);
    }
    70% {
        transform: scale(1.1);
        box-shadow: 0 0 10px 20px rgba(0, 123, 255, 0);
    }
    100% {
        transform: scale(1);
        box-shadow: 0 0 0 0 rgba(0, 123, 255, 0);
    }
}

/* 动画 3: 背景色变化 */
@keyframes color-change {
    0% { background-color: tomato; }
    100% { background-color: mediumpurple; }
}

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

/* 动画 5: 弹跳(用于多重动画) */
@keyframes bounce-y {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-20px); }
}

/* --- 应用动画属性 --- */

/* 示例 1: 基本动画 */
.box-basic {
    animation-name: slide-in;       /* 使用哪个 @keyframes 动画 */
    animation-duration: 0.8s;       /* 动画时长 0.8 秒 */
    /* 其他属性使用默认值:
       animation-timing-function: ease;
       animation-delay: 0s;
       animation-iteration-count: 1;
       animation-direction: normal;
       animation-fill-mode: none;
       animation-play-state: running;
    */
    animation-fill-mode: backwards; /* 演示:动画开始前就应用第一帧状态 */
}

/* 示例 2: 无限循环与速度曲线 */
.box-looping {
    animation-name: pulse;
    animation-duration: 1.5s;
    animation-timing-function: linear;      /* 匀速变化 */
    animation-iteration-count: infinite;    /* 无限循环 */
}

/* 示例 3: 交替方向与填充模式 */
.box-direction-fill {
    animation-name: color-change;
    animation-duration: 2s;
    animation-iteration-count: infinite;
    animation-direction: alternate;        /* 方向:正常 -> 反向 -> 正常 ... */
    animation-fill-mode: forwards;         /* 填充模式:动画结束后保持最后一帧状态 (虽然无限循环看不出来,但如果次数有限就可以) */
    /* 如果 iteration-count 不是 infinite,可以看到 forwards 的效果 */
    /* animation-iteration-count: 2; */
}

/* 示例 4: 延迟与播放次数 */
.box-delay-count {
    animation-name: slide-in;
    animation-duration: 0.6s;
    animation-delay: 1s;               /* 延迟 1 秒开始 */
    animation-iteration-count: 3;      /* 播放 3 次 */
    animation-timing-function: ease-in-out;
}

/* 示例 5: 暂停动画 */
.box-play-state {
    animation-name: spin;
    animation-duration: 3s;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
    animation-play-state: running;        /* 初始状态:播放 */
}
.box-play-state:hover {
    animation-play-state: paused;         /* 鼠标悬停时:暂停 */
}

/* 示例 6: animation 简写属性 */
.box-shorthand {
    /* animation: name duration timing-function delay iteration-count direction fill-mode play-state; */
    /* 只需提供必要的值,其他会使用默认值 */
    animation: color-change 2s ease-in-out 0.5s 4 alternate forwards;
    /* 对应:名称 时长 速度曲线 延迟 次数 方向 填充模式 */
}

/* 示例 7: 应用多个动画 */
.box-multiple {
    /* 用逗号分隔多个动画设置 */
    animation: bounce-y 1.5s ease-in-out infinite, /* 第一个动画:上下弹跳 */
               spin 4s linear infinite reverse;  /* 第二个动画:反向旋转 */
}

案例 3 transforms

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS Transforms 示例</title>
    <link rel="stylesheet" href="11.css">
</head>
<body>

    <h1>CSS Transforms 演示</h1>

    <div class="container">
        <h2>2D 变换 (2D Transforms)</h2>

        <div class="box-container">
            <div class="box box-translate">Translate</div>
            <p>向右下移动 (translate)</p>
        </div>

        <div class="box-container">
            <div class="box box-rotate">Rotate</div>
            <p>旋转 45 度 (rotate)</p>
        </div>

        <div class="box-container">
            <div class="box box-scale">Scale</div>
            <p>放大 1.2 倍 (scale)</p>
        </div>

        <div class="box-container">
            <div class="box box-skew">Skew</div>
            <p>沿 X 轴倾斜 (skewX)</p>
        </div>

        <div class="box-container">
            <div class="box box-matrix">Matrix</div>
            <p>使用 matrix 应用变换</p>
        </div>

        <div class="box-container">
            <div class="box box-origin">Origin</div>
            <p>改变变换原点后旋转 (transform-origin: top left)</p>
        </div>

        <div class="box-container">
            <div class="box box-combo">Combo 2D</div>
            <p>组合变换: 移动、旋转、缩放</p>
        </div>
    </div>

    <div class="container perspective-container">
        <h2>3D 变换 (3D Transforms)</h2>
        <p>注意:需要父容器设置 `perspective` 才能看到 Z 轴效果。</p>

        <div class="box-container">
            <div class="box box-rotateX">Rotate X</div>
            <p>绕 X 轴旋转 (rotateX)</p>
        </div>

        <div class="box-container">
            <div class="box box-rotateY">Rotate Y</div>
            <p>绕 Y 轴旋转 (rotateY)</p>
        </div>

         <div class="box-container">
            <div class="box box-translateZ">Translate Z</div>
            <p>沿 Z 轴移动 (靠近/远离) (translateZ)</p>
        </div>

         <div class="box-container card-container">
            <div class="box card">
                <div class="card-face card-front">Front</div>
                <div class="card-face card-back">Back</div>
            </div>
            <p>3D 翻转卡片 (rotateY + backface-visibility)</p>
        </div>

         <div class="box-container preserve-3d-container">
            <div class="box parent-3d">
                Parent (preserve-3d)
                <div class="box child-3d">Child (rotateY)</div>
            </div>
            <p>嵌套 3D 变换 (transform-style: preserve-3d)</p>
        </div>

    </div>

</body>
</html>
body {
    font-family: sans-serif;
    padding: 20px;
    background-color: #f9f9f9;
}

h1 {
    text-align: center;
    color: #333;
    margin-bottom: 30px;
}
h2 {
    color: steelblue;
    margin-top: 30px;
    margin-bottom: 20px;
    border-bottom: 1px solid #ccc;
    padding-bottom: 5px;
}

.container {
    background-color: #fff;
    padding: 20px;
    margin-bottom: 30px;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.box-container {
    display: inline-block; /* 让容器并排显示 */
    margin: 20px;
    text-align: center;
    vertical-align: top; /* 顶部对齐 */
    width: 150px; /* 给容器一个宽度 */
}

.box-container p {
    font-size: 0.85em;
    color: #555;
    margin-top: 10px;
}

/* 方块基础样式 */
.box {
    width: 100px;
    height: 100px;
    background-color: lightcoral;
    color: white;
    display: flex; /* 使用 flex 居中文本 */
    justify-content: center;
    align-items: center;
    margin: 0 auto; /* 在容器内水平居中 */
    border-radius: 5px;
    transition: transform 0.4s ease-in-out; /* 为所有变换添加过渡效果 */
}

/* 应用变换效果 (通常在 :hover 或类切换时应用) */
/* 为了演示方便,我们直接应用在默认状态 */

/* --- 2D Transforms --- */
.box-translate {
    /* 向右移动 30px, 向下移动 20px */
    transform: translate(30px, 20px);
}

.box-rotate {
    /* 顺时针旋转 45 度 */
    transform: rotate(45deg);
}

.box-scale {
    /* 宽度放大 1.2 倍, 高度缩小到 0.8 倍 */
    transform: scale(1.2, 0.8);
}

.box-skew {
    /* 仅沿 X 轴倾斜 20 度 */
    transform: skewX(20deg);
    /* 试试 skew(10deg, 5deg) */
}

.box-matrix {
    /* 使用 matrix 实现: scale(1.1) rotate(10deg) translate(10px, 5px) */
    /* matrix(scaleX(), skewY(), skewX(), scaleY(), translateX(), translateY()) */
    transform: matrix(1.083, 0.191, -0.191, 1.083, 10, 5); /* 结果是复合效果 */
}

.box-origin {
    transform-origin: top left; /* 将变换原点设置到左上角 */
    transform: rotate(30deg);   /* 现在绕左上角旋转 */
}

.box-combo {
    /* 组合多个变换函数,注意顺序! */
    transform: translateX(20px) rotate(-15deg) scale(0.9);
}

/* --- 3D Transforms --- */

/* 给 3D 变换的父容器设置透视 */
.perspective-container {
    perspective: 800px; /* 设置观察者距离 */
    /* perspective-origin: top right; */ /* 可以改变观察点 */
    background-color: #eef; /* 换个背景色区分 */
}

.box-rotateX {
    /* 绕 X 轴旋转 60 度 */
    transform: rotateX(60deg);
}

.box-rotateY {
     /* 绕 Y 轴旋转 60 度 */
     transform: rotateY(60deg);
}

.box-translateZ {
    /* 沿 Z 轴移动 50px (看起来变大了,靠近观察者) */
    transform: translateZ(50px);
    /* 试试 transform: translateZ(-50px); (看起来变小,远离观察者) */
}

/* 3D 卡片效果 */
.card-container {
    position: relative; /* 为绝对定位的背面提供容器 */
    width: 100px; /* 调整容器尺寸以匹配卡片 */
    height: 100px;
    margin: 20px auto;
}
.card {
    width: 100%;
    height: 100%;
    position: absolute; /* 让正反面重叠 */
    transform-style: preserve-3d; /* 关键:启用 3D 空间 */
    transition: transform 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275); /* 加个过渡 */
    cursor: pointer;
}
.card-face {
    position: absolute;
    width: 100%;
    height: 100%;
    backface-visibility: hidden; /* 关键:隐藏背面 */
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 5px;
    font-weight: bold;
}
.card-front {
    background-color: dodgerblue;
    color: white;
}
.card-back {
    background-color: gold;
    color: #333;
    transform: rotateY(180deg); /* 关键:将背面翻转 180 度 */
}
/* 悬停时翻转卡片 */
.card-container:hover .card {
    transform: rotateY(180deg);
}


/* 嵌套 3D 变换 */
.preserve-3d-container {
    padding-top: 30px; /* 给点空间 */
}
.parent-3d {
    width: 120px;
    height: 120px;
    background-color: rgba(0, 128, 0, 0.7); /* 半透明绿色 */
    position: relative; /* 用于定位子元素 */
    transform-style: preserve-3d; /* 关键:允许子元素在 3D 空间 */
    transform: rotateX(30deg); /* 父元素也旋转一下 */
}
.child-3d {
    width: 80px;
    height: 80px;
    background-color: rgba(255, 0, 0, 0.7); /* 半透明红色 */
    position: absolute;
    top: 20px;
    left: 20px;
    transform: rotateY(45deg) translateZ(30px); /* 子元素在 3D 空间旋转并移出 */
}