先记住这个答案
transform-origin 设定的是旋转和缩放的参考点。默认值是 50% 50%,也就是元素的正中心。把它改成 0 0,rotate(45deg) 就不再绕中心转,而是绕左上角转,元素会甩到右下方去。scale(2) 也一样,中心缩放时元素向四周均匀扩大,改到左上角缩放时元素只会向右下方扩大。
transform-origin默认在元素中心rotate围绕原点旋转,改原点等于改旋转轴scale以原点为不动点向外或向内缩放- 可以接受一到三个值,分别对应 X、Y、Z 轴
旋转时原点位置的区别
想象一张纸钉在桌上,钉子在哪里,纸就绕哪里转。transform-origin 就是那颗钉子。
/* 默认绕中心旋转 */
.card-center {
transform: rotate(45deg);
/* transform-origin 默认 50% 50%,不用写 */
}
/* 绕左上角旋转 */
.card-corner {
transform-origin: 0 0;
transform: rotate(45deg);
}第一个元素原地转了 45 度,视觉上还在原来的位置附近。第二个元素的左上角不动,整个元素像门一样绕铰链甩出去。两段代码唯一的区别就是 transform-origin。
在做「点击展开菜单」的动画时,把原点设在菜单按钮的位置,菜单就会从按钮处旋转展开,比从中心冒出来自然得多。
缩放时原点的作用
缩放的原点就是那个「不动的点」。从中心缩放,元素四个边均匀扩大。从左上角缩放,左上角钉住不动,元素只向右下方扩大。
.thumb {
transform-origin: top left; /* 等同于 0 0 */
transition: transform 200ms ease;
}
.thumb:hover {
transform: scale(1.5); /* 左上角不动,向右下放大 */
}这在图片缩略图悬停放大时很常见。如果缩略图在网格左上角,原点设 top left 就不会超出容器左边和上边。如果缩略图在右下角,就该把原点设成 bottom right。
三个值分别对应什么
transform-origin 可以接受一到三个值。一个值设 X 轴,两个值设 X 和 Y,三个值多出 Z 轴(只在 3D 变换里有意义)。
X 和 Y 可以用关键字(left、center、right / top、center、bottom),也可以用长度或百分比。百分比相对于元素自身宽高,所以 50% 50% 就是中心。Z 轴只能用长度,比如 transform-origin: 50% 50% -100px 表示原点在元素中心偏后 100 像素。
需要注意的是,transform-origin 改的是坐标系的原点位置,并不会移动元素本身。元素的布局位置不会因为设了 transform-origin 而变化。
容易答错的地方
- 以为
transform-origin对translate也有效 translate是纯位移操作,不涉及旋转中心或缩放中心。不管transform-origin设成什么,translateX(50px)的效果都一样。只有rotate、scale、skew这些和参考点有关的函数才受影响。- 把百分比当成相对于父元素
transform-origin: 100% 100%是元素自身的右下角,不是父元素的右下角。这和translate百分比相对自身是同一个规则。
面试官还会怎么问?
做一个从按钮位置展开的下拉菜单,transform-origin 怎么设?
如果按钮在菜单的左上角,菜单的 transform-origin 设成 top left,然后用 scale(0) 到 scale(1) 做过渡。菜单就会从按钮位置「长出来」。如果按钮在右上角,就改成 top right。
transform-origin 和 transform 的顺序有关系吗?
transform-origin 是独立属性,不管写在 transform 前面还是后面都一样。但 transform 里面多个函数的顺序是有影响的,比如先 translate 再 rotate 和先 rotate 再 translate 的效果不同,因为每个函数都在前一个函数变换后的坐标系上操作。
3D 场景里 transform-origin 的 Z 值有什么用?
第三个值设定原点在 Z 轴上的偏移。比如做翻牌效果时,把 transform-origin 的 Z 值设成卡片厚度的一半,旋转时正反两面就能对齐。不过大多数 2D 场景只需要前两个值。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。