第2章:CSS3变换(Transform)基础——让元素动起来的第一步
说实话,CSS3的Transform是我最早接触的动画属性之一。记得刚入行那会儿,要实现一个元素旋转或者位移,还得用JavaScript去操作DOM的style.left、style.top,那叫一个痛苦。后来CSS3的Transform一出来,我整个人都舒服了——原来让元素动起来,可以这么简单。
这一章,咱们就聊聊Transform的四个核心函数:translate()、rotate()、scale()、skew(),以及一个容易被忽略但极其重要的属性——transform-origin。最后,我会带大家实现一个经典的卡片翻转效果。
2.1 认识Transform:它到底改变了什么?
先问一个问题:Transform改变的是元素的什么?
很多人会脱口而出:「位置、大小、角度啊。」
对,但不全对。Transform改变的是元素的视觉呈现,而不是它在文档流中的实际占位。什么意思呢?你想想看,一个元素用了translateX(100px),它看起来往右移了100px,但它在文档流里的原始位置依然占据着空间,其他元素不会自动让位。这一点,我在项目中踩过坑——有一次做弹窗动画,用了translate做位移,结果发现弹窗虽然移走了,但底下的遮罩层点击区域还是原来的位置,排查了半天才反应过来。
核心要点:Transform不会影响文档流,它只改变元素的渲染结果。这意味着你可以随意变换元素,而不用担心打乱布局。
2.2 四个核心函数详解
2.2.1 translate() —— 移动元素
translate() 说白了就是让元素「挪个窝」。它接受两个参数:X轴偏移量和Y轴偏移量。
/* 语法 */
transform: translate(tx, ty);
transform: translateX(tx);
transform: translateY(ty);
/* 示例 */
.box {
transform: translate(50px, 100px); /* 向右移50px,向下移100px */
}
我个人习惯用百分比来做相对位移,比如 translate(50%, 50%),这个百分比是相对于元素自身尺寸的。这在做居中布局时特别好用——配合绝对定位,一个 top: 50%; left: 50%; transform: translate(-50%, -50%) 就能完美居中,不用管父容器多大。
小技巧:translate可以使用负值,比如 translate(-50%, -50%) 就是向左上角移动自身一半的宽高。这在做垂直水平居中时是经典写法。
2.2.2 rotate() —— 旋转元素
rotate() 让元素绕着一个中心点旋转。参数是角度,单位是 deg(degree的缩写)。
/* 语法 */
transform: rotate(angle);
/* 示例 */
.box {
transform: rotate(45deg); /* 顺时针旋转45度 */
transform: rotate(-30deg); /* 逆时针旋转30度 */
}
正值为顺时针,负值为逆时针。这个很好记,你想想看钟表指针怎么走的就明白了。
我曾经在做一个加载动画时,用rotate让一个圆环无限旋转,效果非常丝滑。但要注意,rotate默认的旋转中心是元素的几何中心,也就是50% 50%的位置。如果你想改变旋转中心,那就得用到后面要讲的 transform-origin 了。
2.2.3 scale() —— 缩放元素
scale() 用来放大或缩小元素。参数是缩放倍数,1为原始大小,大于1放大,小于1缩小。
/* 语法 */
transform: scale(sx, sy);
transform: scaleX(sx);
transform: scaleY(sy);
/* 示例 */
.box {
transform: scale(1.5); /* 整体放大1.5倍 */
transform: scale(0.5, 2); /* 宽度缩小一半,高度放大一倍 */
}
这里有个坑,我刚开始用的时候踩过——scale() 只接受一个参数时,它会同时缩放X和Y轴。如果你只想缩放一个方向,用 scaleX() 或 scaleY() 更清晰。
注意:scale缩放的是元素的视觉尺寸,但元素在文档流中的占位空间不变。如果你缩放了一个按钮,它的点击区域还是原来的大小,除非你用 pointer-events 或者重新计算点击区域。
2.2.4 skew() —— 倾斜元素
skew() 可能是四个函数里最不常用的,但某些场景下它非常出彩。它让元素沿着X轴或Y轴发生倾斜变形,参数同样是角度。
/* 语法 */
transform: skew(ax, ay);
transform: skewX(ax);
transform: skewY(ay);
/* 示例 */
.box {
transform: skew(10deg, 5deg); /* X轴倾斜10度,Y轴倾斜5度 */
transform: skewX(20deg); /* 只沿X轴倾斜20度 */
}
你可以把skew想象成把一张纸的一边固定,另一边用力推——纸就变成了平行四边形。这个效果在做一些立体感或者动态背景时很有用。
2.3 transform-origin:控制变换的「支点」
前面提到,rotate、scale、skew默认都是以元素的中心为基准进行变换的。但如果你想让元素绕着左上角旋转,或者从底部开始缩放呢?这时候就需要 transform-origin 出场了。
/* 语法 */
transform-origin: x-position y-position z-position;
/* 常用值 */
transform-origin: center center; /* 默认值,中心点 */
transform-origin: top left; /* 左上角 */
transform-origin: 50% 50%; /* 等同于 center center */
transform-origin: 0 100%; /* 左下角 */
transform-origin: 100px 200px; /* 指定像素位置 */
这个属性接受两个或三个值(3D变换时用第三个值),可以是关键词(top、bottom、left、right、center),也可以是百分比或具体像素值。
我记得有一次做卡片翻转效果,想让卡片从底部「翻」起来,而不是从中间翻。当时默认的transform-origin是center,效果很平淡。改成 transform-origin: bottom center 之后,整个动画的立体感和动感瞬间就出来了。
一句话总结:transform-origin决定了变换的「锚点」。改变它,同样的变换函数会产生完全不同的视觉效果。
2.4 实战:卡片翻转效果
好了,理论知识讲完了。咱们来做一个经典的卡片翻转效果。这个效果在很多网站上都见过——鼠标悬停时,卡片像扑克牌一样翻过来,展示背面的内容。
实现思路其实很简单:
- 准备一个容器,里面放两个面(正面和背面)
- 默认显示正面,背面隐藏
- 鼠标悬停时,让整个容器沿Y轴旋转180度
- 背面在旋转过程中「翻」到前面来
关键代码来了:
<div class="card">
<div class="card-inner">
<div class="card-front">
<h3>正面内容</h3>
<p>悬停我看看背面</p>
</div>
<div class="card-back">
<h3>背面内容</h3>
<p>这是背面的信息</p>
</div>
</div>
</div>
<style>
.card {
width: 300px;
height: 200px;
perspective: 1000px; /* 给父容器添加透视,产生3D效果 */
}
.card-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 0.6s ease;
transform-style: preserve-3d; /* 保留子元素的3D空间 */
}
.card:hover .card-inner {
transform: rotateY(180deg); /* 悬停时翻转180度 */
}
.card-front, .card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden; /* 隐藏背面,防止翻转时看到反面 */
display: flex;
align-items: center;
justify-content: center;
border-radius: 10px;
}
.card-front {
background: #4A90D9;
color: white;
}
.card-back {
background: #F5A623;
color: white;
transform: rotateY(180deg); /* 背面默认旋转180度,这样翻转后它才正面朝前 */
}
</style>
这里有几个关键点,我重点说一下:
- perspective:给父容器设置透视,让翻转有立体感。没有它,翻转就是扁平的,像一张纸在平面上旋转,没有「纵深」的感觉。
- transform-style: preserve-3d:告诉浏览器,子元素要在3D空间里进行变换。如果不加这个,子元素的rotateY会被「拍平」到父元素的平面上。
- backface-visibility: hidden:这个属性很关键。它让元素的背面不可见。默认情况下,一个元素旋转180度后,你会看到它的「背面」(也就是镜像内容)。加上
hidden后,背面就透明了,这样翻转时才能看到另一面的内容。
避坑指南:我曾经在项目中忘记加 transform-style: preserve-3d,结果卡片翻转时两个面「打架」,正面和背面同时出现,画面非常诡异。排查了半天才发现是少了这一行。所以,做3D变换时,这三个属性(perspective、preserve-3d、backface-visibility)最好一起上,缺一不可。
2.5 本章小结
这一章我们聊了CSS3 Transform的四个基础函数:
- translate():移动元素,不影响文档流
- rotate():旋转元素,默认绕中心
- scale():缩放元素,视觉尺寸变化
- skew():倾斜元素,做出平行四边形效果
以及 transform-origin 这个控制变换「支点」的属性,还有 perspective、transform-style、backface-visibility 这三个3D变换的「黄金搭档」。
说实话,Transform是CSS动画的基石。你想想看,后面要学的过渡(Transition)和动画(Animation),本质上都是在不同时间点改变Transform的值。所以这一章的内容,值得你多花点时间消化。
下一章,我们会聊CSS3过渡(Transition),看看如何让这些变换「动起来」,而不是瞬间跳变。到时候,咱们再结合今天学的Transform,做一些更酷的效果。
课后练习:试着把上面卡片翻转的transform-origin改成不同的位置(比如top left、bottom right),看看翻转效果有什么变化。你会发现,同样的代码,不同的支点,视觉感受完全不同。
公众号:蓝海资料掘金营,微信deep3321