pin_drop当前位置:知识文库 ❯ 图文
CSS变换教程-transform属性2D三维变换详解
一、教程简介
CSS transform 属性用于对元素进行2D或3D变换,包括平移、旋转、缩放和倾斜等操作。transform 是 CSS 动画和过渡的核心属性之一,由 GPU 加速渲染,性能优异。本教程将详细讲解 transform 的2D变换、3D变换、变换原点以及组合变换的使用方法。
二、核心概念
2D变换函数
代码示例
/* 平移 */
transform: translate(50px, 30px); /* 水平50px,垂直30px */
transform: translateX(50px); /* 水平平移 */
transform: translateY(30px); /* 垂直平移 */
/* 旋转 */
transform: rotate(45deg); /* 顺时针旋转45度 */
transform: rotate(-30deg); /* 逆时针旋转30度 */
/* 缩放 */
transform: scale(1.5); /* 整体放大1.5倍 */
transform: scale(0.8); /* 整体缩小0.8倍 */
transform: scaleX(2); /* 水平放大2倍 */
transform: scaleY(0.5); /* 垂直缩小0.5倍 */
transform: scale(1.5, 0.8); /* 水平1.5倍,垂直0.8倍 */
/* 倾斜 */
transform: skew(15deg, 10deg); /* 水平倾斜15度,垂直倾斜10度 */
transform: skewX(20deg); /* 水平倾斜 */
transform: skewY(10deg); /* 垂直倾斜 */3D变换函数
代码示例
/* 3D平移 */
transform: translate3d(50px, 30px, 100px);
transform: translateZ(100px);
/* 3D旋转 */
transform: rotate3d(1, 1, 0, 45deg); /* 绕(1,1,0)轴旋转45度 */
transform: rotateX(45deg); /* 绕X轴旋转 */
transform: rotateY(45deg); /* 绕Y轴旋转 */
transform: rotateZ(45deg); /* 绕Z轴旋转 */
/* 3D缩放 */
transform: scale3d(1.5, 1.5, 1);
transform: scaleZ(2);
/* 透视 */
transform: perspective(500px); /* 设置透视距离 */
/* 矩阵变换 */
transform: matrix(a, b, c, d, e, f); /* 2D矩阵 */
transform: matrix3d(...16个值...); /* 3D矩阵 */transform-origin(变换原点)
代码示例
/* 关键字 */
transform-origin: center center; /* 默认:中心点 */
transform-origin: top left; /* 左上角 */
transform-origin: bottom right; /* 右下角 */
/* 百分比 */
transform-origin: 50% 50%; /* 中心 */
transform-origin: 0% 0%; /* 左上角 */
transform-origin: 100% 100%; /* 右下角 */
/* 像素值 */
transform-origin: 20px 30px;
/* 3D原点 */
transform-origin: 50% 50% 100px;3D相关属性
代码示例
/* 透视距离(设在父元素上) */
perspective: 800px;
/* 透视原点 */
perspective-origin: 50% 50%;
/* 3D渲染上下文 */
transform-style: flat; /* 子元素不保留3D位置(默认) */
transform-style: preserve-3d; /* 子元素保留3D位置 */
/* 背面可见性 */
backface-visibility: visible; /* 背面可见(默认) */
backface-visibility: hidden; /* 背面隐藏 */组合变换
代码示例
/* 多个变换函数按顺序应用(从右到左) */
transform: translate(50px, 0) rotate(45deg) scale(1.2);
/* 注意顺序:先旋转再平移 vs 先平移再旋转 */
transform: rotate(45deg) translateX(100px); /* 沿旋转后的方向平移 */
transform: translateX(100px) rotate(45deg); /* 先平移再旋转 */三、代码示例
示例1:2D变换基础
代码示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>2D变换基础</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Microsoft YaHei', sans-serif; background: #f5f5f5; color: #333; padding: 30px; }
h1 { text-align: center; color: #2c3e50; margin-bottom: 30px; }
.section { max-width: 900px; margin: 0 auto 25px; background: white; padding: 25px; border-radius: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); }
.section h2 { color: #34495e; font-size: 18px; margin-bottom: 15px; padding-bottom: 8px; border-bottom: 2px solid #ecf0f1; }
.demo-row { display: flex; flex-wrap: wrap; gap: 20px; justify-content: center; }
.demo-item { text-align: center; }
.demo-item .box { width: 100px; height: 100px; background: linear-gradient(135deg, #667eea, #764ba2); border-radius: 10px; display: flex; align-items: center; justify-content: center; color: white; font-size: 13px; font-weight: bold; margin-bottom: 8px; transition: transform 0.4s ease; }
.demo-item code { font-size: 11px; color: #7f8c8d; font-family: Consolas, monospace; }
/* 平移 */
.t1:hover .box { transform: translateX(30px); }
.t2:hover .box { transform: translateY(-20px); }
.t3:hover .box { transform: translate(30px, -20px); }
/* 旋转 */
.r1:hover .box { transform: rotate(45deg); }
.r2:hover .box { transform: rotate(90deg); }
.r3:hover .box { transform: rotate(180deg); }
/* 缩放 */
.s1:hover .box { transform: scale(1.3); }
.s2:hover .box { transform: scale(0.7); }
.s3:hover .box { transform: scaleX(1.5); }
/* 倾斜 */
.k1:hover .box { transform: skewX(15deg); }
.k2:hover .box { transform: skewY(15deg); }
.k3:hover .box { transform: skew(15deg, 10deg); }
</style>
</head>
<body>
<h1>2D变换基础</h1>
<div class="section">
<h2>translate 平移</h2>
<div class="demo-row">
<div class="demo-item t1"><div class="box">X+30</div><code>translateX(30px)</code></div>
<div class="demo-item t2"><div class="box">Y-20</div><code>translateY(-20px)</code></div>
<div class="demo-item t3"><div class="box">XY</div><code>translate(30px,-20px)</code></div>
</div>
</div>
<div class="section">
<h2>rotate 旋转</h2>
<div class="demo-row">
<div class="demo-item r1"><div class="box">45</div><code>rotate(45deg)</code></div>
<div class="demo-item r2"><div class="box">90</div><code>rotate(90deg)</code></div>
<div class="demo-item r3"><div class="box">180</div><code>rotate(180deg)</code></div>
</div>
</div>
<div class="section">
<h2>scale 缩放</h2>
<div class="demo-row">
<div class="demo-item s1"><div class="box">1.3</div><code>scale(1.3)</code></div>
<div class="demo-item s2"><div class="box">0.7</div><code>scale(0.7)</code></div>
<div class="demo-item s3"><div class="box">X1.5</div><code>scaleX(1.5)</code></div>
</div>
</div>
<div class="section">
<h2>skew 倾斜</h2>
<div class="demo-row">
<div class="demo-item k1"><div class="box">X15</div><code>skewX(15deg)</code></div>
<div class="demo-item k2"><div class="box">Y15</div><code>skewY(15deg)</code></div>
<div class="demo-item k3"><div class="box">XY</div><code>skew(15deg,10deg)</code></div>
</div>
</div>
</body>
</html>示例2:3D变换效果
代码示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D变换效果</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Microsoft YaHei', sans-serif; background: #1a1a2e; color: #eee; padding: 30px; }
h1 { text-align: center; color: #64ffda; margin-bottom: 30px; }
.container { max-width: 1000px; margin: 0 auto; }
.section { background: #16213e; padding: 25px; border-radius: 10px; margin-bottom: 25px; border: 1px solid #2a2a4a; }
.section h2 { color: #64ffda; font-size: 16px; margin-bottom: 15px; }
/* 3D旋转展示 */
.rotate3d-row { display: flex; gap: 30px; justify-content: center; flex-wrap: wrap; }
.rotate3d-item { text-align: center; }
.rotate3d-item .box { width: 100px; height: 100px; background: linear-gradient(135deg, #667eea, #764ba2); border-radius: 10px; display: flex; align-items: center; justify-content: center; color: white; font-size: 13px; font-weight: bold; transition: transform 0.6s ease; }
.rotate3d-item code { font-size: 11px; color: #a0a0c0; font-family: Consolas, monospace; display: block; margin-top: 8px; }
.rx:hover .box { transform: perspective(400px) rotateX(60deg); }
.ry:hover .box { transform: perspective(400px) rotateY(60deg); }
.rz:hover .box { transform: perspective(400px) rotateZ(45deg); }
/* 翻转卡片 */
.flip-card { width: 240px; height: 160px; perspective: 800px; margin: 0 auto; }
.flip-inner { width: 100%; height: 100%; position: relative; transition: transform 0.6s; transform-style: preserve-3d; }
.flip-card:hover .flip-inner { transform: rotateY(180deg); }
.flip-front, .flip-back { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 18px; font-weight: bold; }
.flip-front { background: linear-gradient(135deg, #3498db, #2980b9); color: white; }
.flip-back { background: linear-gradient(135deg, #e74c3c, #c0392b); color: white; transform: rotateY(180deg); }
/* 立方体 */
.cube-wrapper { perspective: 800px; width: 150px; height: 150px; margin: 30px auto; }
.cube { width: 150px; height: 150px; position: relative; transform-style: preserve-3d; animation: cubeRotate 8s linear infinite; }
@keyframes cubeRotate { from { transform: rotateX(0) rotateY(0); } to { transform: rotateX(360deg) rotateY(360deg); } }
.cube-face { position: absolute; width: 150px; height: 150px; border: 2px solid rgba(100,255,218,0.3); display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: bold; color: #64ffda; background: rgba(22,33,62,0.8); }
.face-front { transform: translateZ(75px); }
.face-back { transform: rotateY(180deg) translateZ(75px); }
.face-right { transform: rotateY(90deg) translateZ(75px); }
.face-left { transform: rotateY(-90deg) translateZ(75px); }
.face-top { transform: rotateX(90deg) translateZ(75px); }
.face-bottom { transform: rotateX(-90deg) translateZ(75px); }
</style>
</head>
<body>
<h1>3D变换效果</h1>
<div class="container">
<div class="section">
<h2>3D旋转(悬停查看)</h2>
<div class="rotate3d-row">
<div class="rotate3d-item rx"><div class="box">X轴</div><code>rotateX(60deg)</code></div>
<div class="rotate3d-item ry"><div class="box">Y轴</div><code>rotateY(60deg)</code></div>
<div class="rotate3d-item rz"><div class="box">Z轴</div><code>rotateZ(45deg)</code></div>
</div>
</div>
<div class="section">
<h2>翻转卡片</h2>
<div class="flip-card">
<div class="flip-inner">
<div class="flip-front">正面</div>
<div class="flip-back">背面</div>
</div>
</div>
</div>
<div class="section">
<h2>3D立方体</h2>
<div class="cube-wrapper">
<div class="cube">
<div class="cube-face face-front">前</div>
<div class="cube-face face-back">后</div>
<div class="cube-face face-right">右</div>
<div class="cube-face face-left">左</div>
<div class="cube-face face-top">上</div>
<div class="cube-face face-bottom">下</div>
</div>
</div>
</div>
</div>
</body>
</html>示例3:transform实战组件
代码示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>transform实战组件</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Microsoft YaHei', sans-serif; background: #f0f2f5; color: #333; padding: 30px; }
h1 { text-align: center; color: #2c3e50; margin-bottom: 30px; }
.container { max-width: 1000px; margin: 0 auto; }
.section { background: white; padding: 25px; border-radius: 12px; margin-bottom: 25px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); }
.section h2 { color: #34495e; font-size: 18px; margin-bottom: 15px; padding-bottom: 8px; border-bottom: 2px solid #ecf0f1; }
/* 悬停放大卡片 */
.card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; }
.hover-card { background: white; border-radius: 12px; padding: 20px; text-align: center; border: 1px solid #eee; transition: transform 0.3s ease, box-shadow 0.3s ease; cursor: pointer; }
.hover-card:hover { transform: translateY(-8px) scale(1.02); box-shadow: 0 10px 30px rgba(0,0,0,0.12); }
.hover-card .icon { width: 50px; height: 50px; border-radius: 12px; margin: 0 auto 12px; display: flex; align-items: center; justify-content: center; font-size: 24px; color: white; }
.hover-card h3 { font-size: 15px; color: #2c3e50; margin-bottom: 5px; }
.hover-card p { font-size: 12px; color: #95a5a6; }
/* 按钮点击效果 */
.btn-row { display: flex; gap: 12px; flex-wrap: wrap; }
.btn { padding: 12px 28px; border: none; border-radius: 8px; font-size: 14px; cursor: pointer; font-weight: bold; transition: transform 0.15s ease; }
.btn:active { transform: scale(0.95); }
.btn-primary { background: #3498db; color: white; }
.btn-success { background: #27ae60; color: white; }
.btn-danger { background: #e74c3c; color: white; }
/* 图片悬停效果 */
.img-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 15px; }
.img-wrapper { overflow: hidden; border-radius: 10px; cursor: pointer; }
.img-wrapper .img { height: 140px; background-size: cover; background-position: center; transition: transform 0.5s ease; }
.img-wrapper:hover .img { transform: scale(1.1); }
/* 倾斜卡片 */
.tilt-row { display: flex; gap: 15px; justify-content: center; flex-wrap: wrap; }
.tilt-card { width: 150px; height: 100px; background: linear-gradient(135deg, #667eea, #764ba2); border-radius: 10px; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; transition: transform 0.3s ease; cursor: pointer; }
.tilt-card:hover { transform: perspective(500px) rotateY(10deg) rotateX(5deg); }
</style>
</head>
<body>
<div class="container">
<h1>transform 实战组件</h1>
<div class="section">
<h2>悬停放大卡片</h2>
<div class="card-grid">
<div class="hover-card"><div class="icon" style="background: #3498db;">A</div><h3>功能模块</h3><p>translateY + scale</p></div>
<div class="hover-card"><div class="icon" style="background: #27ae60;">B</div><h3>数据分析</h3><p>translateY + scale</p></div>
<div class="hover-card"><div class="icon" style="background: #e74c3c;">C</div><h3>系统设置</h3><p>translateY + scale</p></div>
</div>
</div>
<div class="section">
<h2>按钮点击缩放</h2>
<div class="btn-row">
<button class="btn btn-primary">主要按钮</button>
<button class="btn btn-success">成功按钮</button>
<button class="btn btn-danger">危险按钮</button>
</div>
</div>
<div class="section">
<h2>图片悬停缩放</h2>
<div class="img-grid">
<div class="img-wrapper"><div class="img" style="background-image: linear-gradient(135deg, #667eea, #764ba2);"></div></div>
<div class="img-wrapper"><div class="img" style="background-image: linear-gradient(135deg, #f093fb, #f5576c);"></div></div>
<div class="img-wrapper"><div class="img" style="background-image: linear-gradient(135deg, #4facfe, #00f2fe);"></div></div>
</div>
</div>
<div class="section">
<h2>3D倾斜卡片</h2>
<div class="tilt-row">
<div class="tilt-card">悬停倾斜</div>
<div class="tilt-card" style="background: linear-gradient(135deg, #f093fb, #f5576c);">悬停倾斜</div>
<div class="tilt-card" style="background: linear-gradient(135deg, #4facfe, #00f2fe);">悬停倾斜</div>
</div>
</div>
</div>
</body>
</html>四、浏览器兼容性
五、注意事项与最佳实践
注意事项
-
变换不影响文档流:
transform不会影响其他元素的布局,元素仍占据原始空间 -
变换顺序很重要:
rotate(45deg) translateX(100px)和translateX(100px) rotate(45deg)效果不同 -
百分比参照:
translate的百分比参照元素自身尺寸,其他变换函数不支持百分比 -
3D变换需要perspective:3D效果需要设置
perspective才有深度感 -
层叠上下文:设置
transform的元素会创建新的层叠上下文
最佳实践
-
性能优先:优先使用
transform代替top/left等定位属性做动画 -
GPU加速:使用
transform: translateZ(0)或will-change: transform触发GPU加速 -
变换原点:根据需要调整
transform-origin,如旋转动画常用center center -
3D场景:3D变换组合使用
perspective+transform-style: preserve-3d -
硬件加速:避免在大量元素上同时使用3D变换
六、代码规范示例
不推荐的写法
代码示例
/* 不推荐:用top/left做动画 */
.box { transition: top 0.3s, left 0.3s; position: absolute; }
.box:hover { top: 50px; left: 100px; }
/* 不推荐:忽略变换顺序 */
.box { transform: translateX(100px) rotate(45deg); } /* 可能不是预期效果 */
/* 不推荐:过度使用3D */
.box { transform: translateZ(0) rotateX(0) rotateY(0); } /* 不必要的3D */推荐的写法
代码示例
/* 推荐:用transform做动画 */
.box { transition: transform 0.3s ease; }
.box:hover { transform: translate(100px, 50px); }
/* 推荐:明确变换顺序(先旋转再平移) */
.box { transform: rotate(45deg) translateX(100px); }
/* 推荐:仅在需要时使用3D */
.card-wrapper { perspective: 800px; }
.card { transform-style: preserve-3d; transition: transform 0.6s; }
.card:hover { transform: rotateY(180deg); }七、常见问题与解决方案
常见问题
3D变换没有深度效果怎么办?
原因是缺少 perspective 属性。在父元素上设置 perspective: 800px,或在 transform 中使用 perspective() 函数即可解决。
翻转卡片背面可见怎么处理?
原因是未设置 backface-visibility: hidden。为正面和背面元素都添加此属性即可解决。
transform导致文字模糊如何解决?
原因是非整数像素的 translate 或 scale 导致亚像素渲染。使用整数值,或在动画结束后移除 transform,或添加 translateZ(0) 强制GPU渲染。
八、总结
CSS transform 是实现2D/3D变换的核心属性,支持 translate(平移)、rotate(旋转)、scale(缩放)、skew(倾斜)四大变换函数,以及对应的3D版本。变换不影响文档流,由GPU加速渲染,性能优异。在实际开发中,应优先使用 transform 代替定位属性做动画,注意变换顺序,合理使用 perspective 和 transform-style: preserve-3d 创建3D效果。核心原则是:优先GPU加速、注意变换顺序、合理使用3D、不影响文档流。
本文涉及AI创作
内容由AI创作,请仔细甄别