CSS Handbook · 变换与动画

第八章 / 8.1 transform 详解

第八章 · 8.1 节

transform 详解


transform 允许对元素进行平移、缩放、旋转、倾斜,且这些变化不会影响文档流——周围元素不会因为一个元素被旋转或缩放而重新排布,这也是它区别于 width/margin 等布局属性的关键特性。

2D 变换函数

函数作用示例
translate()位移translate(20px, -10px)
scale()缩放,1 为原始大小scale(1.1)
rotate()旋转rotate(15deg)
skew()倾斜skew(10deg, 0)
悬停查看效果(若为静态截图请脑补:鼠标悬停时卡片上浮并轻微放大)
translateY
rotate
scale
.btn { transition: transform .2s ease; }
.btn:hover { transform: translateY(-2px); }

transform-origin:变换基准点

所有变换都围绕一个"基准点"进行,默认是元素中心 50% 50%。修改基准点能显著改变旋转、缩放的观感——比如把基准点移到左上角,旋转就会表现为"以左上角为轴心甩开",而不是原地打转。

.flip-card {
  transform-origin: left center;
  transform: rotateY(20deg);
}

组合多个变换

多个变换函数写在同一个 transform 声明里,用空格分隔,从左到右依次生效——调换顺序会得到不同结果,这是初学者最容易踩的坑。

/* 先平移再旋转:整体绕新位置旋转 */
.a { transform: translate(40px, 0) rotate(45deg); }

/* 先旋转再平移:平移方向也跟着旋转了 */
.b { transform: rotate(45deg) translate(40px, 0); }
心智模型把每个变换函数想象成对"坐标系本身"的操作而非对元素的操作:先执行的函数会重新定义后续函数所处的坐标系,因此顺序调换后结果不同。

3D 变换初步

在父元素上开启 perspective,子元素才能表现出真正的透视深度效果,否则 rotateX / rotateY 只会呈现为扁平的拉伸。

.scene { perspective: 800px; }
.card {
  transform: rotateY(25deg);
  transform-style: preserve-3d;
}

transform-style: preserve-3d 让子元素的 3D 变换保留在同一个三维空间中,而不是被父元素"拍扁",这是制作立体翻转卡片一类效果的关键声明。

为什么 transform 性能更好

修改 width、top 这类布局属性会触发浏览器重新计算页面布局(reflow),代价较高;而 transform 与 opacity 通常可以直接交由 GPU 合成层处理,跳过布局与绘制阶段。这也是为什么几乎所有动效场景都建议优先用 transform: translate() 代替 left/top 位移元素。

Chapter 8 · Section 8.1

transform in Depth


transform lets you translate, scale, rotate, and skew elements, and these changes do not affect the document flow — surrounding elements are not re-laid out just because one element is rotated or scaled. This is the key property that sets it apart from layout properties like width and margin.

2D Transform Functions

FunctionEffectExample
translate()Translationtranslate(20px, -10px)
scale()Scaling; 1 is the original sizescale(1.1)
rotate()Rotationrotate(15deg)
skew()Skewingskew(10deg, 0)
Hover to see the effect (if this is a static screenshot, imagine: hovering lifts the card up and scales it up slightly)
translateY
rotate
scale
.btn { transition: transform .2s ease; }
.btn:hover { transform: translateY(-2px); }

transform-origin: The Transformation Reference Point

Every transformation happens around a "reference point", by default the element's center, 50% 50%. Moving the reference point noticeably changes how rotation and scaling look — for example, moving it to the top-left corner makes rotation appear as "swinging around the top-left corner" rather than spinning in place.

.flip-card {
  transform-origin: left center;
  transform: rotateY(20deg);
}

Combining Multiple Transforms

Multiple transform functions go in the same transform declaration, separated by spaces, and take effect from left to right — swapping the order gives different results, which is one of the most common traps for beginners.

/* translate first, then rotate: the whole element rotates around its new position */
.a { transform: translate(40px, 0) rotate(45deg); }

/* rotate first, then translate: the translation direction is rotated too */
.b { transform: rotate(45deg) translate(40px, 0); }
Mental modelThink of each transform function as an operation on the "coordinate system itself" rather than on the element: a function executed first redefines the coordinate system for the functions that follow, which is why swapping the order yields different results.

3D Transforms, a First Look

Only when perspective is enabled on the parent element do children show real perspective depth; otherwise rotateX / rotateY just look like flat stretches.

.scene { perspective: 800px; }
.card {
  transform: rotateY(25deg);
  transform-style: preserve-3d;
}

transform-style: preserve-3d keeps a child's 3D transforms in the same three-dimensional space instead of being "flattened" by the parent — the key declaration behind effects like 3D flip cards.

Why transform Is Faster

Changing layout properties like width or top forces the browser to recalculate the page layout (reflow), which is expensive; transform and opacity, on the other hand, can usually be handled directly by the GPU compositor, skipping the layout and paint stages. That is why almost every animation scenario recommends moving elements with transform: translate() instead of left/top.