目录

1. Transform:几何变换

1.1 什么是 transform(渲染与原理)

1.2 语法与执行顺序

1.3 变换原点:transform-origin

1.4 各类 2D 变换函数

1) 平移 translate

2) 缩放 scale

3) 旋转 rotate

4) 倾斜 skew

1.5 3D 变换(核心函数)

1.6 透视与 3D 场景

1.7 独立属性:translate / scale / rotate(Transforms Level 2)

1.8 参考盒与命中测试:transform-box

1.9 叠层与层叠上下文

1.10 性能与优化

2. Transition:让“状态变化”平滑可感

2.1 概念与触发机制

2.2 语法与速查表

2.3 可过渡属性与 “auto” 陷阱

2.4 多属性与时间曲线

2.5 事件:监听过渡生命周期

2.6 实战技巧

3. Animation:时间轴动画与关键帧

3.1 关键帧与速查表

3.2 循环、方向、填充模式、暂停

3.3 steps() 与逐帧动画

3.4 与 transform 的组合与拆分

3.5 无障碍与系统偏好

4. Transform × Transition × Animation 选型与范式

5. 实战案例(可直接粘贴运行)

5.1 变换演示场(hover 触发,transition 实现)

5.2 3D 翻牌(preserve-3d + backface-visibility)

5.3 关键帧:旋转移动缩放一体

5.4 展开/收起:max-height + transform 双保险

6. 常见问题

7. 结语


1. Transform:几何变换

1.1 什么是 transform(渲染与原理)

transform 是 CSS3 引入的几何变形属性。它可在二维/三维空间里对盒子进行平移、缩放、旋转、倾斜与矩阵变换。不改变文档流:元素的布局占位不变,视觉上被“拿起来”在独立坐标系里变形。

渲染关键点:

  • 不触发重排(reflow),通常只触发重绘或直接在合成层上完成(GPU 参与),因此性能优

  • transform创建新的层叠上下文,影响 z-index、叠放顺序与固定定位的表现。

  • 命中测试(点击区域)默认基于变换后图形(大部分浏览器),但滚动容器/溢出剪裁等边界场景要留意(见 1.8)。

1.2 语法与执行顺序

transform: <transform-function> [<transform-function> ...];
  • 顺序重要:矩阵乘法是非交换的。translate → rotaterotate → translate 结果完全不同。

  • 示例(先平移再旋转再缩放):

transform: translateX(100px) rotate(30deg) scale(1.2);

思维模型:从右到左看“坐标系的变换”(数学上),但 CSS 直观上按书写顺序逐步应用即可,牢记“写在前面的先执行”。

1.3 变换原点:transform-origin

定义旋转/缩放/倾斜的基准点(对平移无效)。默认 50% 50%(元素中心)。

.box {
  transform-origin: center center; /* 默认 */
  /* 常见写法 */
  transform-origin: top left;
  transform-origin: 100% 50%;
  transform-origin: 50% 150%; /* 在元素外的延伸点也可 */
}

变换原点可配合 scalerotate 设计“从某角展开/收缩”的动画。

1.4 各类 2D 变换函数

1) 平移 translate
transform: translateX(100px);
transform: translateY(-50px);
transform: translate(100px, -50px); /* 同时设置 x 与 y */
  • % 相对自身尺寸translateX(50%) 为自身宽度一半)。

  • 不改变文档占位,适合替代 left/top 做动效。

2) 缩放 scale
transform: scale(2);        /* 等比放大 */
transform: scaleX(1.5);     /* 仅 x 方向 */
transform: scaleY(0.8);     /* 仅 y 方向 */
transform: scale(1.2, 0.8); /* 非等比 */
  • 缩放中心受 transform-origin 控制。

  • 文本缩放可能出现锯齿/模糊,可视需要用 translateZ(0)/backface-visibility 缓解,或避免极端缩放。

3) 旋转 rotate
transform: rotate(45deg); /* 正为顺时针,负为逆时针 */
  • 支持 degradturn(如 rotate(0.5turn))。

4) 倾斜 skew
transform: skewX(30deg);   /* 沿X轴倾斜30° */
transform: skewY(15deg);   /* 沿Y轴倾斜15° */
transform: skew(30deg, 15deg);
  • 使坐标轴成非直角关系,适合做斜边卡片等效果。

1.5 3D 变换(核心函数)

transform: translateZ(100px);     /* 前后(z轴) */
transform: translate3d(x,y,z);
transform: rotateX(45deg);
transform: rotateY(60deg);
transform: rotateZ(30deg);        /* 等价 2D rotate */
transform: rotate3d(x, y, z, angle);

z 轴正方向指向观察者,“数值越大越靠前”。

1.6 透视与 3D 场景

  • 透视(景深):可在父元素上设置

    .scene { perspective: 800px; perspective-origin: 50% 50%; }
    

    或在元素上用函数(影响该元素自身变换链)

    .card { transform: perspective(800px) rotateY(45deg); }
    
  • 子元素保留 3D

    .parent { transform-style: preserve-3d; }
    

    默认 flat 会将子元素压扁到 2D 平面。

  • 背面可见性

    .face { backface-visibility: hidden; }
    

    常用于翻牌,避免背面镜像闪烁。

1.7 独立属性:translate / scale / rotate(Transforms Level 2)

除了 transform: ... 复合写法,现代浏览器支持独立变换属性

.box {
  translate: 20px 0;   /* 等价 transform: translate(20px) */
  scale: 1.1;          /* 等价 transform: scale(1.1) */
  rotate: 15deg;       /* 等价 transform: rotate(15deg) */
}

优势:

  • 更易与其他函数合成覆盖

  • 与动画/过渡搭配时可独立控制某一维度变换;

  • 未来与 motion-path 等特性结合更直观。

1.8 参考盒与命中测试:transform-box

决定 % 等相对量参考的几何盒(对 HTML 元素通常是 border-box;对 SVG 非常有用):

transform-box: border-box | fill-box | view-box;

命中测试与滚动要点:

  • 变换后元素的可点击区域通常随之改变(以变换后几何为准)。

  • overflow: hidden 的容器裁剪可能影响交互区域。

  • 开启 3D 或大量合成层时,注意层顺序对命中测试的影响。

1.9 叠层与层叠上下文

transform 会创建新的层叠上下文,它影响:

  • z-index 的比较范围;

  • position: fixedfilteropacity 等并用时的绘制顺序

  • 可能改变 position: fixed 元素的参照(例如位于变换元素内时)。

1.10 性能与优化

  • 优先用 transform/opacity 做动效,避免 top/left/width/height

  • 合理使用:

    will-change: transform;
    /* 或搭配 */
    contain: paint; /* 限定绘制范围,避免外溢重绘 */
    
  • 警惕:

    • 过多合成层(内存占用、上传纹理成本);

    • 极端 scale 导致字体/位图模糊;

    • 反复触发强制同步布局(避免 JS 在动画过程中读取布局)。


2. Transition:让“状态变化”平滑可感

2.1 概念与触发机制

transition 不会主动产生动画,它监听属性值的变化(如状态类名切换、伪类 :hover、JS 改样式等),并在给定时间内平滑过渡

2.2 语法与速查表

transition: <property> <duration> <timing-function> <delay>;
/* 可多条逗号分隔 */
transition: transform .3s ease, opacity .2s linear .1s;

常用:

  • transition-property: 具体属性或 all

  • transition-duration: ms/s

  • transition-timing-function:

    • ease | linear | ease-in | ease-out | ease-in-out

    • cubic-bezier(x1, y1, x2, y2)(自定义)

    • steps(n, start|end)(阶跃)

  • transition-delay: 延迟

2.3 可过渡属性与 “auto” 陷阱

  • 大部分数值型属性可过渡(含 transformopacity)。

  • height: auto 不可直接过渡。常见替代:

    • max-height0 → 某大值

    • 或用 scaleY(配 transform-origin: top)视觉展开;

    • 或用 grid-template-rows/clip-path 等技巧。

2.4 多属性与时间曲线

  • 多个属性可分别设置时长/曲线:

    transition:
      transform .35s cubic-bezier(.2,.7,.3,1),
      opacity .2s ease-out .1s;
    
  • steps(n) 适合“打字机”“逐帧跳变”。

2.5 事件:监听过渡生命周期

JS 可监听:

  • transitionrun(过渡已排入队列)

  • transitionstart(开始)

  • transitionend(结束)

  • transitioncancel(被打断)

2.6 实战技巧

  • 悬停抬升

    .card { transition: transform .2s ease, box-shadow .2s; }
    .card:hover { transform: translateY(-6px); box-shadow: 0 12px 24px rgba(0,0,0,.12); }
    
  • 手风琴(max-height 技法):

    .panel { max-height: 0; overflow: hidden; transition: max-height .35s ease; }
    .panel.open { max-height: 600px; } /* 600 设为足以容纳内容的值 */
    
  • 禁用首次动画闪烁:初次渲染无动画,增加“就绪”类后才让过渡生效。


3. Animation:时间轴动画与关键帧

3.1 关键帧与速查表

@keyframes spin-move {
  0%   { transform: translateX(0) rotate(0deg); }
  50%  { transform: translateX(140px) rotate(180deg) scale(1.1); }
  100% { transform: translateX(0) rotate(360deg); }
}

.box {
  animation: spin-move 3s ease-in-out .2s infinite alternate both running;
}

animation 简写依次包含:

  • name / duration / timing-function / delay / iteration-count / direction / fill-mode / play-state

3.2 循环、方向、填充模式、暂停

  • 循环:animation-iteration-count: infinite | <number>

  • 方向:normal | reverse | alternate | alternate-reverse

  • 填充:none | forwards | backwards | both

  • 暂停/恢复:animation-play-state: paused | running

3.3 steps() 与逐帧动画

@keyframes type {
  from { width: 0ch; }
  to   { width: 24ch; }
}
.typing {
  animation: type 2s steps(24, end) forwards;
  overflow: hidden; white-space: nowrap;
}
  • 或者用背景图/雪碧图 + steps() 做帧动画。

3.4 与 transform 的组合与拆分

  • 复杂动画建议拆分多个关键帧或使用独立属性translate/rotate/scale)以减少覆盖冲突。

  • 也可将“位移动效”放 transform,“透明/色彩变化”放 opacity/filter,分层控制。

3.5 无障碍与系统偏好

尊重用户“减少动画”偏好:

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: 0s !important; }
}

4. Transform × Transition × Animation 选型与范式

  • 一次性、被动的状态切换(如 hover、展开/收起):transition + transform

  • 自动播放、循环、多阶段animation + transform

  • 性能优先:尽量只动画 transformopacity

  • 可维护性:优先使用独立变换属性translate/scale/rotate)或拆分关键帧


5. 实战案例

5.1 变换演示场(hover 触发,transition 实现)

<!DOCTYPE html><html lang="zh-CN"><meta charset="utf-8"><title>Transform 基本演示</title>
<style>
*{box-sizing:border-box} body{font:16px/1.6 system-ui, -apple-system, Segoe UI, Roboto}
.wrap{display:grid;grid-template-columns:repeat(5, 160px);gap:20px;justify-content:center;margin:48px auto;max-width:1000px}
.box{height:100px;border:1px solid #ddd;display:flex;align-items:center;justify-content:center;transition:transform .35s ease;background:#f7f7f7}
.t-translate:hover{transform:translateX(80px)}
.t-scale:hover{transform-origin:left center;transform:scale(1.4)}
.t-rotate:hover{transform:rotate(30deg)}
.t-skew:hover{transform:skew(15deg, 0)}
.t-combo:hover{transform:translate(50px, -12px) rotate(20deg) scale(1.2)}
</style>
<div class="wrap">
  <div class="box t-translate">translate</div>
  <div class="box t-scale">scale</div>
  <div class="box t-rotate">rotate</div>
  <div class="box t-skew">skew</div>
  <div class="box t-combo">combo</div>
</div>
</html>

5.2 3D 翻牌(preserve-3d + backface-visibility)

<!DOCTYPE html><html lang="zh-CN"><meta charset="utf-8"><title>3D 卡片翻转</title>
<style>
.scene{perspective:900px;display:flex;justify-content:center;margin-top:80px}
.card{width:240px;height:160px;position:relative;transform-style:preserve-3d;transition:transform .8s cubic-bezier(.2,.7,.2,1)}
.card:hover{transform:rotateY(180deg)}
.face{position:absolute;inset:0;display:grid;place-items:center;font:600 18px/1.2 system-ui;border:1px solid #ddd;background:#fff}
.back{transform:rotateY(180deg);backface-visibility:hidden}
.front{backface-visibility:hidden}
</style>
<div class="scene">
  <div class="card">
    <div class="face front">Front</div>
    <div class="face back">Back</div>
  </div>
</div>
</html>

5.3 关键帧:旋转移动缩放一体

<!DOCTYPE html><html lang="zh-CN"><meta charset="utf-8"><title>Animation + Transform</title>
<style>
.stage{height:260px;display:grid;place-items:center}
.dot{width:24px;height:24px;border-radius:50%;background:#e86;animation:orbit 3s ease-in-out .2s infinite alternate both}
@keyframes orbit{
  0%{ transform:translate(0, 0) rotate(0deg) scale(1) }
  50%{ transform:translate(160px, -40px) rotate(180deg) scale(1.25) }
  100%{ transform:translate(0, 0) rotate(360deg) scale(1) }
}
</style>
<div class="stage"><div class="dot"></div></div>
</html>

5.4 展开/收起:max-height + transform 双保险

<!DOCTYPE html><html lang="zh-CN"><meta charset="utf-8"><title>手风琴</title>
<style>
.btn{display:inline-block;padding:.5em 1em;border:1px solid #ddd;cursor:pointer;margin:12px 0}
.panel{max-height:0;overflow:hidden;transition:max-height .35s ease;transform-origin:top}
.panel.open{max-height:500px}
.content{padding:.75em 0;border-top:1px dashed #ddd}
</style>
<div class="btn" onclick="p.classList.toggle('open')">切换</div>
<div id="p" class="panel"><div class="content">
  这里是内容。现实项目里 max-height 设为足够大的值(如 500/800),避免 auto 过渡问题。
</div></div>
<script>const p=document.getElementById('p')</script>
</html>

6. 常见问题

Q1:为什么我 z-index 失效了?
A:transform 创建了新的层叠上下文。比较 z-index 需在同一上下文内。将相关元素放在同一上下文,或在父级控制 z-index

Q2:height: auto 为什么不动?
A:auto 不可插值。用 max-heightscaleYgrid 技巧替代。

Q3:文字旋转或缩放后发虚?
A:尝试避免极端缩放;可用 backface-visibility: hidden;translateZ(0) 或字体渲染优化;有时改用 filter: blur(0) 触发优化也能改善,但要评估性能。

Q4:3D 翻转时背面穿帮?
A:确保父级 perspective、自身 transform-style: preserve-3d,正反两面都加 backface-visibility: hidden;

Q5:动画导致页面滚动卡顿?
A:减小动画区域、减少合成层数量;只动画 transform/opacity;必要时添加 will-change: transform,并避免长时间保留。

Q6:transitionend 没有触发?
A:确认确实有“数值变化”,并且过渡的 duration > 0;同时确保监听的是实际变化的属性名

Q7:命中测试不准?
A:多数浏览器以变换后几何为准;但注意 overflow 剪裁、层顺序与 pointer-events 设置;复杂 3D 场景中考虑为交互元素单独设更高层或透明命中层。


7. 结语

  • Transform 决定“形态怎么变”;

  • Transition 让“状态切换”变得自然;

  • Animation 则给你完整的“时间轴与循环控制”。

三者并用,可以在纯 CSS(几乎不依赖 JS)的前提下,完成从微交互到立体场景的绝大多数动效需求。

更多推荐