1576 字
8 分钟

transform复合变换的坐标系变换详解

欢迎来到我的博客!#

这是我的第 4 篇文章,使用 Markdown 格式编写。

今天学到了什么#

  • 今天来做一篇大文章,分享一个transform的知识点(搞了一晚上和两早上,终于搞明白了

是在完成这个案例的时候,遇到的问题

PixPin_2025-12-07_10-54-37

这个案例需要将一个面设置为底面,这两个面需要设置position: absolute;

为什么这两个面需要设置position: absolute;?#

因为很明显,这是一个动效案例,并且需要两个盒子,

其次,transform只是在视觉上调整元素的位置,但是它的本体(变换前的位置)还是要占空间的,这时候如果不脱离普通的文档流,就很难实现,尤其是需要多个盒子实现的效果,这个盒子的位置会影响另一个盒子的位置,很难调整,所以我们需要脱离普通的文档流,让两个盒子的位置互不影响,才能更好地实现案例

总结:什么时候用 position: absolute;?

  1. 需要脱离文档流 :不希望元素影响其他元素的布局。
  2. 需要相对于父元素定位 :比如居中、叠加、或者精确定位。
  3. 需要完全重叠 :比如实现遮罩、背景层、或者 3D 效果。
  4. 需要固定在某个位置 :比如右下角按钮、弹窗等。
  5. 需要动画或 3D 效果 :让元素在父元素内自由移动或变换。

接下来,我们就要分别设置两个面的位置,正面容易设置,关键是底面,当做底面的那个盒子,需要先旋转,然后再向下平移到合适的位置。

首先要理解以下知识点

translate() 的本质:始终是“相对初始位置的偏移量”#

  • translate(300px, 600px) 的意思是: 让元素从它的初始位置,整体偏移 300px(右)、600px(下) 。
  • 它不是“累计”移动,也不是“每一步都在上一步的基础上再移动”,而是 直接跳到这个偏移量的位置 。

在做的过程中,有很多注意点容易让人产生疑惑#

  1. 首先,先说明一个点,在CSS当中,利用坐标轴定位并不像数学中的那样,
  2. 在数学中的坐标轴,是用一个个准确的坐标点来定位的,所以坐标原点这个概念是很重要的,只有设置好坐标原点的位置,才能更好地确定图形的位置。
  3. 而在CSS当中,“坐标原点”其实并不重要 ,因为各种元素平移到合适位置,利用的是 元素目标位置相对元素初始位置,在当前坐标轴方向上移动指定的距离,简单来讲,相对于元素初始位置的偏移量 。才是CSS当中 元素定位的核心,
  4. 差别就很明显了,数学中的定位是目标点相对坐标原点的距离,而CSS当中的定位是元素目标位置相对元素初始位置的距离,区别就是是否强化了坐标原点在元素定位当中的重要性(或者是目标定位的参照位置不一样)
  5. 理解这些,才能理解CSS确定元素位置的方式

上述主要讨论了平移的核心逻辑,接下来讨论平移和旋转的区别#

绕轴旋转和平移利用坐标轴的方式,本质上是一样的,坐标轴的方向才是关键,其他的,比如坐标原点之类的,并不重要

image-20251207131309556

我一开始以为CSS中元素默认的坐标轴位置是这样的,那绕X轴旋转,不应该是向上转吗?实际上绕轴旋转的默认位置,这样设计是为了灵活性,不是bug——如果旋转轴默认在顶部,很多动画会不直观。

这再次说明了一个点,即坐标轴的位置并不重要,更重要的是坐标轴的方向

transform的复合变换规则#

image-20251207132633648

你看见了吗,中间那个蓝色的平面就是加了rotate的底部盒子,我现在就是要让它下移到白色平面的底部。

但是要注意一个点,旋转后,元素本地坐标系也旋转了,z轴是向下的,这时候我想让盒子从视觉上向下移动,不是应该写 translateZ 吗?

但是实际上并不是,这里就是关键点了

<style>
ul li .bottom {
background: #3b5999;
color: #fff;
transform: rotateX(-90deg) translateY(20px);
/* 改变默认旋转轴
transform-origin: bottom; */
transform-origin: center;
/* 改为以自身底部为旋转中心 */
transform-origin: bottom;
}
</style>

transform-origin: bottom;这句话是改为以li的底部(也就是父元素的底部)为bottom的旋转中心,不是改为以它本身的底部为旋转中心

反正目前我的理解是,父元素设置了preserve-3d后 子元素的变换,是根据父元素的坐标系来进行变换的,而不是根据自己本地的这个坐标轴变化的。

之后有问题再说吧。

以上就是我总结的核心知识点,下面的就是代码展示了

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="http://at.alicdn.com/t/c/font_4096975_pswyqyk8tdo.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #ccc;
}
ul {
display: flex;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
gap: 5px;
/* border: 1px solid #262626;
background-color: #262626; */
perspective: 800px;
}
ul li {
width: 80px;
height: 40px;
position: relative;
/* 初始化 去掉前面的点*/
list-style: none;
/* 这里我虽然写在了li里面,但是由于span可以继承li的样式,所以图标仍然会居中显示 */
/* text-align: center;
line-height: 40px; */
font-size: 20px;
transition: all 0.5s ease-in-out;
transform-style: preserve-3d;
}
ul li span {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
/* position: absolute; */
/* 加了定位后自动变成块级元素了 */
display: block;
text-align: center;
line-height: 40px;
}
ul li .front {
background: #fff;
color: #3b5999;
transform: translateZ(20px);
}
ul li .bottom {
background: #3b5999;
color: #fff;
transform: translateY(20px) rotateX(-90deg);
}
ul li:hover {
transform: rotateX(90deg);
}
</style>
</head>
<body>
<ul>
<li>
<span class="front iconfont icon-QQ"></span>
<span class="bottom iconfont icon-QQ"></span>
</li>
<li>
<span class="front iconfont icon-weixin"></span>
<span class="bottom iconfont icon-weixin"></span>
</li>
<li>
<span class="front iconfont icon-douyin"></span>
<span class="bottom iconfont icon-douyin"></span>
</li>
<li>
<span class="front iconfont icon-xinlangweibo"></span>
<span class="bottom iconfont icon-xinlangweibo"></span>
</li>
<li>
<span class="front iconfont icon-shouji"></span>
<span class="bottom iconfont icon-shouji"></span>
</li>
</ul>
</body>
</html>

赞助支持

如果这篇文章对你有帮助,欢迎赞助支持!

赞助
transform复合变换的坐标系变换详解
https://firefly.cuteleaf.cn/posts/study-everyday/2025-12-7今日学习-关于transform/
作者
LJC
发布于
2025-12-07
许可协议
CC BY-NC-SA 4.0
最后更新于 2025-12-07,距今已过 28 天

部分内容可能已过时

目录