轩辕李的博客 轩辕李的博客
首页
  • Java
  • Spring
  • 其他语言
  • 工具
  • JavaScript
  • TypeScript
  • Node.js
  • Vue.js
  • 前端工程化
  • 浏览器与Web API
  • 分布式
  • 代码质量管理
  • 基础
  • 操作系统
  • 计算机网络
  • 编程范式
  • 安全
  • 中间件
  • 心得
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

轩辕李

勇猛精进,星辰大海
首页
  • Java
  • Spring
  • 其他语言
  • 工具
  • JavaScript
  • TypeScript
  • Node.js
  • Vue.js
  • 前端工程化
  • 浏览器与Web API
  • 分布式
  • 代码质量管理
  • 基础
  • 操作系统
  • 计算机网络
  • 编程范式
  • 安全
  • 中间件
  • 心得
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • JavaScript

  • TypeScript

  • Node.js

  • Vue.js

  • 工程化

  • 浏览器与Web API

    • HTML基础-语义化标签与文档结构
    • HTML基础-文本与排版标签
    • HTML基础-列表与表格
    • HTML表单-Input类型详解
    • HTML表单-表单元素与验证
    • HTML交互-多媒体元素
    • HTML工程化-模板与组件化
    • HTML工程化-性能优化
    • CSS基础-选择器与优先级
    • CSS基础-盒模型与布局基础
    • CSS基础-单位与颜色系统
    • CSS基础-文本与字体
    • CSS基础-背景、列表与表格样式
    • CSS布局-Flexbox完全指南
    • CSS布局-Grid网格布局
    • CSS布局-响应式设计实践
    • CSS进阶-动画与过渡
    • CSS进阶-渐变与阴影效果
    • CSS进阶-Transform与3D变换
      • 一、Transform基础
        • 1.1 什么是Transform
        • 1.2 Transform-Origin
      • 二、2D变换
        • 2.1 平移(Translate)
        • 2.2 旋转(Rotate)
        • 2.3 缩放(Scale)
        • 2.4 倾斜(Skew)
        • 2.5 组合变换
      • 三、3D变换
        • 3.1 透视(Perspective)
        • 3.2 透视原点(Perspective-Origin)
        • 3.3 3D旋转
        • 3.4 3D平移
        • 3.5 Transform-Style
        • 3.6 Backface-Visibility
      • 四、3D实战案例
        • 4.1 翻转卡片
        • 4.2 3D立方体
        • 4.3 旋转木马(Carousel)
        • 4.4 悬浮效果
      • 五、性能优化与最佳实践
        • 5.1 性能考虑
        • 硬件加速
        • Will-Change
        • 避免重排和重绘
        • 5.2 浏览器兼容性
        • Transform兼容性
        • 3D Transform兼容性
        • 5.3 最佳实践
        • 1. 合理使用Transform
        • 2. 注意变换顺序
        • 3. 3D效果优化
        • 4. 动画性能
        • 5.4 调试技巧
        • Chrome DevTools
        • 常见问题
      • 六、总结
    • CSS进阶-滤镜与混合模式
    • 现代CSS-CSS预处理器对比
    • 现代CSS-CSS-in-JS方案
    • 现代CSS-原子化CSS与Tailwind
    • CSS工程化-架构与规范
    • CSS工程化-性能优化
    • CSS工程化-PostCSS实战指南
    • Web API基础-DOM操作完全指南
    • Web API基础-事件处理与委托
    • Web API基础-BOM与浏览器环境
    • Web API存储-客户端存储方案
    • Web API网络-HTTP请求详解
    • Web API网络-实时通信方案
    • Web API交互-用户体验增强
    • HTML&CSS历代版本新特性
  • 前端
  • 浏览器与Web API
轩辕李
2019-08-13
目录

CSS进阶-Transform与3D变换

CSS Transform 是一个强大的变换工具,允许我们对元素进行旋转、缩放、倾斜和位移等操作。配合3D变换,更能创造出令人惊叹的视觉效果和交互体验。

本文将深入介绍CSS的 transform 属性,包括2D变换(translate、rotate、scale、skew)和3D变换(perspective、rotateX/Y/Z),帮助你掌握各种变换技巧和3D效果的实现。

# 一、Transform基础

# 1.1 什么是Transform

transform 属性允许你对元素进行变换操作,而不影响文档流中的其他元素。变换包括2D和3D两种类型。

基本语法:

transform: function1(value) function2(value) ...;

特点:

  • 不影响文档流布局
  • 可以组合多个变换函数
  • 触发GPU加速,性能优秀
  • 支持动画和过渡

# 1.2 Transform-Origin

transform-origin 定义变换的基点(原点),默认是元素的中心点。

/* 默认值:中心点 */
transform-origin: center center;

/* 使用关键字 */
transform-origin: top left;
transform-origin: bottom right;

/* 使用百分比 */
transform-origin: 50% 50%;

/* 使用具体数值 */
transform-origin: 20px 30px;

/* 3D变换还可以设置Z轴 */
transform-origin: 50% 50% 100px;
<html>
  <div class="origin-demo-b8e4c3">
    <div class="box-b8e4c3 center-b8e4c3">center</div>
    <div class="box-b8e4c3 top-left-b8e4c3">top left</div>
    <div class="box-b8e4c3 bottom-right-b8e4c3">bottom right</div>
  </div>
</html>
<style>
.origin-demo-b8e4c3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  padding: 20px;
}
.box-b8e4c3 {
  width: 100px;
  height: 100px;
  background: linear-gradient(135deg, #667eea, #764ba2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  font-size: 12px;
  cursor: pointer;
  transition: transform 0.3s;
  margin: 20px;
}
.center-b8e4c3 {
  transform-origin: center center;
}
.center-b8e4c3:hover {
  transform: rotate(45deg);
}
.top-left-b8e4c3 {
  transform-origin: top left;
}
.top-left-b8e4c3:hover {
  transform: rotate(45deg);
}
.bottom-right-b8e4c3 {
  transform-origin: bottom right;
}
.bottom-right-b8e4c3:hover {
  transform: rotate(45deg);
}
</style>

# 二、2D变换

# 2.1 平移(Translate)

translate() 函数用于移动元素位置。

/* 水平和垂直方向同时移动 */
transform: translate(50px, 100px);

/* 只水平移动 */
transform: translateX(50px);

/* 只垂直移动 */
transform: translateY(100px);

/* 使用百分比(相对于元素自身尺寸) */
transform: translate(50%, 50%);
<html>
  <div class="translate-demo-b8e4c3">
    <div class="container-b8e4c3">
      <div class="box-b8e4c3 original-b8e4c3">原始位置</div>
      <div class="box-b8e4c3 translate-x-b8e4c3">translateX</div>
      <div class="box-b8e4c3 translate-y-b8e4c3">translateY</div>
      <div class="box-b8e4c3 translate-both-b8e4c3">translate</div>
    </div>
  </div>
</html>
<style>
.translate-demo-b8e4c3 {
  padding: 20px;
}
.container-b8e4c3 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 80px;
  padding: 40px;
}
.translate-demo-b8e4c3 .box-b8e4c3 {
  width: 120px;
  height: 80px;
  background: linear-gradient(135deg, #667eea, #764ba2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  font-size: 14px;
  transition: transform 0.3s;
  cursor: pointer;
}
.original-b8e4c3:hover {
  background: linear-gradient(135deg, #f093fb, #f5576c);
}
.translate-x-b8e4c3:hover {
  transform: translateX(30px);
}
.translate-y-b8e4c3:hover {
  transform: translateY(20px);
}
.translate-both-b8e4c3:hover {
  transform: translate(20px, 20px);
}
</style>

应用场景:

  • 居中定位
  • 动画效果
  • 悬停交互
/* 完美居中 */
.center {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

# 2.2 旋转(Rotate)

rotate() 函数用于旋转元素。

/* 顺时针旋转45度 */
transform: rotate(45deg);

/* 逆时针旋转(负值) */
transform: rotate(-45deg);

/* 使用弧度单位 */
transform: rotate(0.785rad);

/* 使用圈数单位 */
transform: rotate(0.125turn);
<html>
  <div class="rotate-demo-b8e4c3">
    <div class="box-b8e4c3 rotate-45-b8e4c3">45deg</div>
    <div class="box-b8e4c3 rotate-90-b8e4c3">90deg</div>
    <div class="box-b8e4c3 rotate-180-b8e4c3">180deg</div>
    <div class="box-b8e4c3 rotate-360-b8e4c3">360deg</div>
  </div>
</html>
<style>
.rotate-demo-b8e4c3 {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
  padding: 40px;
}
.rotate-demo-b8e4c3 .box-b8e4c3 {
  width: 100px;
  height: 100px;
  background: linear-gradient(135deg, #667eea, #764ba2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  cursor: pointer;
  transition: transform 0.5s;
  margin: 0 auto;
}
.rotate-45-b8e4c3:hover {
  transform: rotate(45deg);
}
.rotate-90-b8e4c3:hover {
  transform: rotate(90deg);
}
.rotate-180-b8e4c3:hover {
  transform: rotate(180deg);
}
.rotate-360-b8e4c3:hover {
  transform: rotate(360deg);
}
</style>

持续旋转动画:

<html>
  <div class="rotating-demo-b8e4c3">
    <div class="spinner-b8e4c3"></div>
  </div>
</html>
<style>
.rotating-demo-b8e4c3 {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 40px;
}
.spinner-b8e4c3 {
  width: 60px;
  height: 60px;
  border: 4px solid rgba(102, 126, 234, 0.2);
  border-top-color: #667eea;
  border-radius: 50%;
  animation: spin-b8e4c3 1s linear infinite;
}
@keyframes spin-b8e4c3 {
  to {
    transform: rotate(360deg);
  }
}
</style>

# 2.3 缩放(Scale)

scale() 函数用于缩放元素。

/* 水平和垂直同时缩放 */
transform: scale(1.5);

/* 分别设置水平和垂直缩放 */
transform: scale(2, 0.5);

/* 只水平缩放 */
transform: scaleX(1.5);

/* 只垂直缩放 */
transform: scaleY(0.8);
<html>
  <div class="scale-demo-b8e4c3">
    <div class="box-b8e4c3 scale-up-b8e4c3">放大</div>
    <div class="box-b8e4c3 scale-down-b8e4c3">缩小</div>
    <div class="box-b8e4c3 scale-x-b8e4c3">水平拉伸</div>
    <div class="box-b8e4c3 scale-y-b8e4c3">垂直拉伸</div>
  </div>
</html>
<style>
.scale-demo-b8e4c3 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 60px;
  padding: 60px;
}
.scale-demo-b8e4c3 .box-b8e4c3 {
  width: 100px;
  height: 100px;
  background: linear-gradient(135deg, #667eea, #764ba2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  cursor: pointer;
  transition: transform 0.3s;
  margin: 0 auto;
}
.scale-up-b8e4c3:hover {
  transform: scale(1.3);
}
.scale-down-b8e4c3:hover {
  transform: scale(0.7);
}
.scale-x-b8e4c3:hover {
  transform: scaleX(1.5);
}
.scale-y-b8e4c3:hover {
  transform: scaleY(1.5);
}
</style>

应用场景:

  • 悬停放大效果
  • 图片缩略图交互
  • 按钮点击反馈
/* 图片悬停放大 */
.image-card img {
  transition: transform 0.3s;
}
.image-card:hover img {
  transform: scale(1.1);
}

/* 按钮点击效果 */
.button:active {
  transform: scale(0.95);
}

# 2.4 倾斜(Skew)

skew() 函数用于倾斜元素。

/* 水平和垂直同时倾斜 */
transform: skew(20deg, 10deg);

/* 只水平倾斜 */
transform: skewX(20deg);

/* 只垂直倾斜 */
transform: skewY(10deg);
<html>
  <div class="skew-demo-b8e4c3">
    <div class="box-b8e4c3 original-b8e4c3">原始</div>
    <div class="box-b8e4c3 skew-x-b8e4c3">skewX</div>
    <div class="box-b8e4c3 skew-y-b8e4c3">skewY</div>
    <div class="box-b8e4c3 skew-both-b8e4c3">skew</div>
  </div>
</html>
<style>
.skew-demo-b8e4c3 {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
  padding: 40px;
}
.skew-demo-b8e4c3 .box-b8e4c3 {
  width: 100px;
  height: 100px;
  background: linear-gradient(135deg, #667eea, #764ba2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  cursor: pointer;
  transition: transform 0.3s;
  margin: 0 auto;
}
.skew-x-b8e4c3:hover {
  transform: skewX(20deg);
}
.skew-y-b8e4c3:hover {
  transform: skewY(10deg);
}
.skew-both-b8e4c3:hover {
  transform: skew(15deg, 10deg);
}
</style>

# 2.5 组合变换

可以同时应用多个变换函数,注意顺序很重要:

/* 先旋转再平移 */
transform: rotate(45deg) translate(50px, 0);

/* 先平移再旋转(结果不同) */
transform: translate(50px, 0) rotate(45deg);
<html>
  <div class="combine-demo-b8e4c3">
    <div class="example-b8e4c3">
      <div class="box-b8e4c3 rotate-then-translate-b8e4c3">
        先旋转<br>后平移
      </div>
    </div>
    <div class="example-b8e4c3">
      <div class="box-b8e4c3 translate-then-rotate-b8e4c3">
        先平移<br>后旋转
      </div>
    </div>
  </div>
</html>
<style>
.combine-demo-b8e4c3 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
  padding: 60px 20px;
}
.example-b8e4c3 {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 150px;
}
.combine-demo-b8e4c3 .box-b8e4c3 {
  width: 100px;
  height: 100px;
  background: linear-gradient(135deg, #667eea, #764ba2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  text-align: center;
  font-size: 14px;
  line-height: 1.4;
  cursor: pointer;
  transition: transform 0.5s;
}
.rotate-then-translate-b8e4c3:hover {
  transform: rotate(45deg) translateX(40px);
}
.translate-then-rotate-b8e4c3:hover {
  transform: translateX(40px) rotate(45deg);
}
</style>

复杂组合示例:

<html>
  <div class="complex-demo-b8e4c3">
    <div class="card-b8e4c3">
      <div class="front-b8e4c3">鼠标悬停</div>
      <div class="back-b8e4c3">组合变换</div>
    </div>
  </div>
</html>
<style>
.complex-demo-b8e4c3 {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 80px 20px;
  perspective: 1000px;
}
.card-b8e4c3 {
  width: 200px;
  height: 120px;
  position: relative;
  cursor: pointer;
  transform-style: preserve-3d;
  transition: transform 0.6s;
}
.card-b8e4c3:hover {
  transform: rotateY(180deg) scale(1.1);
}
.front-b8e4c3, .back-b8e4c3 {
  position: absolute;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  font-size: 18px;
  border-radius: 12px;
  backface-visibility: hidden;
}
.front-b8e4c3 {
  background: linear-gradient(135deg, #667eea, #764ba2);
}
.back-b8e4c3 {
  background: linear-gradient(135deg, #f093fb, #f5576c);
  transform: rotateY(180deg);
}
</style>

# 三、3D变换

# 3.1 透视(Perspective)

perspective 定义3D元素距离视点的距离,创造近大远小的效果。

/* 在父元素上设置透视 */
.container {
  perspective: 1000px;
}

/* 或者直接在transform中使用 */
.element {
  transform: perspective(1000px) rotateY(45deg);
}

两种设置方式的区别:

<html>
  <div class="perspective-demo-b8e4c3">
    <div class="container-b8e4c3 parent-perspective-b8e4c3">
      <div class="box-b8e4c3">父元素perspective</div>
      <div class="box-b8e4c3">父元素perspective</div>
    </div>
    <div class="container-b8e4c3 self-perspective-b8e4c3">
      <div class="box-b8e4c3">自身perspective</div>
      <div class="box-b8e4c3">自身perspective</div>
    </div>
  </div>
</html>
<style>
.perspective-demo-b8e4c3 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 40px;
  padding: 40px;
}
.container-b8e4c3 {
  display: flex;
  gap: 20px;
  justify-content: center;
}
.parent-perspective-b8e4c3 {
  perspective: 600px;
}
.perspective-demo-b8e4c3 .box-b8e4c3 {
  width: 120px;
  height: 80px;
  background: linear-gradient(135deg, #667eea, #764ba2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  font-size: 12px;
  text-align: center;
  cursor: pointer;
  transition: transform 0.5s;
}
.parent-perspective-b8e4c3 .box-b8e4c3:hover {
  transform: rotateY(45deg);
}
.self-perspective-b8e4c3 .box-b8e4c3:hover {
  transform: perspective(600px) rotateY(45deg);
}
</style>

# 3.2 透视原点(Perspective-Origin)

perspective-origin 定义观察者的位置。

.container {
  perspective: 1000px;
  perspective-origin: 50% 50%; /* 默认值:中心 */
  perspective-origin: left top;
  perspective-origin: 100% 0%;
}
<html>
  <div class="perspective-origin-demo-b8e4c3">
    <div class="viewer-b8e4c3 center-b8e4c3">
      <div class="box-b8e4c3">center</div>
    </div>
    <div class="viewer-b8e4c3 left-b8e4c3">
      <div class="box-b8e4c3">left</div>
    </div>
    <div class="viewer-b8e4c3 right-b8e4c3">
      <div class="box-b8e4c3">right</div>
    </div>
  </div>
</html>
<style>
.perspective-origin-demo-b8e4c3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  padding: 40px;
}
.viewer-b8e4c3 {
  perspective: 600px;
  height: 150px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.center-b8e4c3 {
  perspective-origin: center center;
}
.left-b8e4c3 {
  perspective-origin: left center;
}
.right-b8e4c3 {
  perspective-origin: right center;
}
.perspective-origin-demo-b8e4c3 .box-b8e4c3 {
  width: 100px;
  height: 100px;
  background: linear-gradient(135deg, #667eea, #764ba2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  cursor: pointer;
  transition: transform 0.5s;
}
.perspective-origin-demo-b8e4c3 .box-b8e4c3:hover {
  transform: rotateY(45deg);
}
</style>

# 3.3 3D旋转

3D旋转包括 rotateX、rotateY、rotateZ 和 rotate3d。

/* 绕X轴旋转(上下翻转) */
transform: rotateX(45deg);

/* 绕Y轴旋转(左右翻转) */
transform: rotateY(45deg);

/* 绕Z轴旋转(平面旋转,等同于rotate) */
transform: rotateZ(45deg);

/* 绕任意轴旋转 */
transform: rotate3d(1, 1, 0, 45deg);
<html>
  <div class="rotate3d-demo-b8e4c3">
    <div class="scene-b8e4c3">
      <div class="box-b8e4c3 rotate-x-b8e4c3">rotateX</div>
    </div>
    <div class="scene-b8e4c3">
      <div class="box-b8e4c3 rotate-y-b8e4c3">rotateY</div>
    </div>
    <div class="scene-b8e4c3">
      <div class="box-b8e4c3 rotate-z-b8e4c3">rotateZ</div>
    </div>
    <div class="scene-b8e4c3">
      <div class="box-b8e4c3 rotate-3d-b8e4c3">rotate3d</div>
    </div>
  </div>
</html>
<style>
.rotate3d-demo-b8e4c3 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 60px;
  padding: 60px;
}
.scene-b8e4c3 {
  perspective: 800px;
  display: flex;
  justify-content: center;
  align-items: center;
}
.rotate3d-demo-b8e4c3 .box-b8e4c3 {
  width: 120px;
  height: 120px;
  background: linear-gradient(135deg, #667eea, #764ba2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  cursor: pointer;
  transition: transform 0.6s;
}
.rotate-x-b8e4c3:hover {
  transform: rotateX(60deg);
}
.rotate-y-b8e4c3:hover {
  transform: rotateY(60deg);
}
.rotate-z-b8e4c3:hover {
  transform: rotateZ(45deg);
}
.rotate-3d-b8e4c3:hover {
  transform: rotate3d(1, 1, 0, 60deg);
}
</style>

# 3.4 3D平移

3D平移包括 translateZ 和 translate3d。

/* Z轴平移(靠近或远离视点) */
transform: translateZ(100px);

/* 3D平移(X, Y, Z) */
transform: translate3d(50px, 100px, 200px);
<html>
  <div class="translate3d-demo-b8e4c3">
    <div class="scene-b8e4c3">
      <div class="box-b8e4c3 translate-z-near-b8e4c3">靠近视点</div>
    </div>
    <div class="scene-b8e4c3">
      <div class="box-b8e4c3 translate-z-far-b8e4c3">远离视点</div>
    </div>
  </div>
</html>
<style>
.translate3d-demo-b8e4c3 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 40px;
  padding: 60px;
}
.translate3d-demo-b8e4c3 .scene-b8e4c3 {
  perspective: 600px;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 200px;
}
.translate3d-demo-b8e4c3 .box-b8e4c3 {
  width: 120px;
  height: 120px;
  background: linear-gradient(135deg, #667eea, #764ba2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  cursor: pointer;
  transition: transform 0.5s;
}
.translate-z-near-b8e4c3:hover {
  transform: translateZ(100px);
}
.translate-z-far-b8e4c3:hover {
  transform: translateZ(-100px);
}
</style>

# 3.5 Transform-Style

transform-style 决定子元素是否保留3D空间。

/* 平面模式(默认) */
transform-style: flat;

/* 3D空间模式 */
transform-style: preserve-3d;
<html>
  <div class="transform-style-demo-b8e4c3">
    <div class="cube-container-b8e4c3 flat-b8e4c3">
      <div class="cube-b8e4c3">
        <div class="face-b8e4c3 front-b8e4c3">前</div>
        <div class="face-b8e4c3 back-b8e4c3">后</div>
      </div>
      <p>flat</p>
    </div>
    <div class="cube-container-b8e4c3 preserve-b8e4c3">
      <div class="cube-b8e4c3">
        <div class="face-b8e4c3 front-b8e4c3">前</div>
        <div class="face-b8e4c3 back-b8e4c3">后</div>
      </div>
      <p>preserve-3d</p>
    </div>
  </div>
</html>
<style>
.transform-style-demo-b8e4c3 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 40px;
  padding: 60px 20px;
}
.cube-container-b8e4c3 {
  perspective: 800px;
  text-align: center;
}
.cube-b8e4c3 {
  width: 150px;
  height: 150px;
  position: relative;
  margin: 0 auto 20px;
  cursor: pointer;
  transition: transform 1s;
}
.flat-b8e4c3 .cube-b8e4c3 {
  transform-style: flat;
}
.preserve-b8e4c3 .cube-b8e4c3 {
  transform-style: preserve-3d;
}
.cube-container-b8e4c3:hover .cube-b8e4c3 {
  transform: rotateY(180deg);
}
.face-b8e4c3 {
  position: absolute;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  font-size: 24px;
  border-radius: 8px;
}
.front-b8e4c3 {
  background: linear-gradient(135deg, #667eea, #764ba2);
  transform: translateZ(75px);
}
.back-b8e4c3 {
  background: linear-gradient(135deg, #f093fb, #f5576c);
  transform: rotateY(180deg) translateZ(75px);
}
.cube-container-b8e4c3 p {
  color: #666;
  font-weight: bold;
  margin: 0;
}
</style>

# 3.6 Backface-Visibility

backface-visibility 决定元素背面是否可见。

/* 背面可见(默认) */
backface-visibility: visible;

/* 背面不可见 */
backface-visibility: hidden;
<html>
  <div class="backface-demo-b8e4c3">
    <div class="card-wrapper-b8e4c3">
      <div class="card-b8e4c3 visible-b8e4c3">
        <div class="side-b8e4c3">背面可见</div>
      </div>
      <p>visible</p>
    </div>
    <div class="card-wrapper-b8e4c3">
      <div class="card-b8e4c3 hidden-b8e4c3">
        <div class="side-b8e4c3">背面隐藏</div>
      </div>
      <p>hidden</p>
    </div>
  </div>
</html>
<style>
.backface-demo-b8e4c3 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 40px;
  padding: 60px 20px;
}
.card-wrapper-b8e4c3 {
  perspective: 800px;
  text-align: center;
}
.backface-demo-b8e4c3 .card-b8e4c3 {
  width: 150px;
  height: 100px;
  margin: 0 auto 20px;
  cursor: pointer;
  transition: transform 1s;
}
.card-wrapper-b8e4c3:hover .card-b8e4c3 {
  transform: rotateY(180deg);
}
.side-b8e4c3 {
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, #667eea, #764ba2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  border-radius: 8px;
}
.visible-b8e4c3 .side-b8e4c3 {
  backface-visibility: visible;
}
.hidden-b8e4c3 .side-b8e4c3 {
  backface-visibility: hidden;
}
.card-wrapper-b8e4c3 p {
  color: #666;
  font-weight: bold;
  margin: 0;
}
</style>

# 四、3D实战案例

# 4.1 翻转卡片

经典的卡片翻转效果:

<html>
  <div class="flip-card-demo-b8e4c3">
    <div class="flip-card-b8e4c3">
      <div class="flip-card-inner-b8e4c3">
        <div class="flip-card-front-b8e4c3">
          <h3>前端开发</h3>
          <p>点击翻转</p>
        </div>
        <div class="flip-card-back-b8e4c3">
          <h3>技能栈</h3>
          <ul>
            <li>HTML/CSS</li>
            <li>JavaScript</li>
            <li>Vue/React</li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</html>
<style>
.flip-card-demo-b8e4c3 {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 60px 20px;
  perspective: 1000px;
}
.flip-card-b8e4c3 {
  width: 300px;
  height: 200px;
  cursor: pointer;
}
.flip-card-inner-b8e4c3 {
  position: relative;
  width: 100%;
  height: 100%;
  transition: transform 0.6s;
  transform-style: preserve-3d;
}
.flip-card-b8e4c3:hover .flip-card-inner-b8e4c3 {
  transform: rotateY(180deg);
}
.flip-card-front-b8e4c3, .flip-card-back-b8e4c3 {
  position: absolute;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 20px;
  box-sizing: border-box;
}
.flip-card-front-b8e4c3 {
  background: linear-gradient(135deg, #667eea, #764ba2);
  color: white;
}
.flip-card-back-b8e4c3 {
  background: linear-gradient(135deg, #f093fb, #f5576c);
  color: white;
  transform: rotateY(180deg);
}
.flip-card-front-b8e4c3 h3, .flip-card-back-b8e4c3 h3 {
  margin: 0 0 10px 0;
  font-size: 24px;
}
.flip-card-front-b8e4c3 p {
  margin: 0;
  opacity: 0.9;
}
.flip-card-back-b8e4c3 ul {
  list-style: none;
  padding: 0;
  margin: 10px 0 0 0;
}
.flip-card-back-b8e4c3 li {
  padding: 5px 0;
  opacity: 0.9;
}
</style>

# 4.2 3D立方体

创建一个完整的3D立方体:

<html>
  <div class="cube-3d-demo-b8e4c3">
    <div class="cube-scene-b8e4c3">
      <div class="cube-3d-b8e4c3">
        <div class="cube-face-b8e4c3 front-b8e4c3">前</div>
        <div class="cube-face-b8e4c3 back-b8e4c3">后</div>
        <div class="cube-face-b8e4c3 right-b8e4c3">右</div>
        <div class="cube-face-b8e4c3 left-b8e4c3">左</div>
        <div class="cube-face-b8e4c3 top-b8e4c3">上</div>
        <div class="cube-face-b8e4c3 bottom-b8e4c3">下</div>
      </div>
    </div>
  </div>
</html>
<style>
.cube-3d-demo-b8e4c3 {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 80px 20px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 12px;
}
.cube-scene-b8e4c3 {
  width: 200px;
  height: 200px;
  perspective: 800px;
}
.cube-3d-b8e4c3 {
  width: 100%;
  height: 100%;
  position: relative;
  transform-style: preserve-3d;
  animation: rotate-cube-b8e4c3 10s infinite linear;
  cursor: pointer;
}
.cube-3d-b8e4c3:hover {
  animation-play-state: paused;
}
@keyframes rotate-cube-b8e4c3 {
  0% {
    transform: rotateX(0deg) rotateY(0deg);
  }
  100% {
    transform: rotateX(360deg) rotateY(360deg);
  }
}
.cube-face-b8e4c3 {
  position: absolute;
  width: 200px;
  height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32px;
  font-weight: bold;
  color: white;
  border: 2px solid rgba(255, 255, 255, 0.3);
  opacity: 0.9;
}
.front-b8e4c3 {
  background: rgba(255, 107, 107, 0.8);
  transform: translateZ(100px);
}
.back-b8e4c3 {
  background: rgba(78, 205, 196, 0.8);
  transform: rotateY(180deg) translateZ(100px);
}
.right-b8e4c3 {
  background: rgba(243, 156, 18, 0.8);
  transform: rotateY(90deg) translateZ(100px);
}
.left-b8e4c3 {
  background: rgba(155, 89, 182, 0.8);
  transform: rotateY(-90deg) translateZ(100px);
}
.top-b8e4c3 {
  background: rgba(52, 152, 219, 0.8);
  transform: rotateX(90deg) translateZ(100px);
}
.bottom-b8e4c3 {
  background: rgba(46, 204, 113, 0.8);
  transform: rotateX(-90deg) translateZ(100px);
}
</style>

# 4.3 旋转木马(Carousel)

3D旋转木马效果:

<html>
  <div class="carousel-demo-b8e4c3">
    <div class="carousel-scene-b8e4c3">
      <div class="carousel-b8e4c3">
        <div class="carousel-item-b8e4c3" style="--i: 0">1</div>
        <div class="carousel-item-b8e4c3" style="--i: 1">2</div>
        <div class="carousel-item-b8e4c3" style="--i: 2">3</div>
        <div class="carousel-item-b8e4c3" style="--i: 3">4</div>
        <div class="carousel-item-b8e4c3" style="--i: 4">5</div>
        <div class="carousel-item-b8e4c3" style="--i: 5">6</div>
      </div>
    </div>
  </div>
</html>
<style>
.carousel-demo-b8e4c3 {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 120px 20px;
}
.carousel-scene-b8e4c3 {
  width: 300px;
  height: 200px;
  perspective: 1000px;
}
.carousel-b8e4c3 {
  width: 100%;
  height: 100%;
  position: relative;
  transform-style: preserve-3d;
  animation: rotate-carousel-b8e4c3 20s infinite linear;
  cursor: pointer;
}
.carousel-b8e4c3:hover {
  animation-play-state: paused;
}
@keyframes rotate-carousel-b8e4c3 {
  to {
    transform: rotateY(360deg);
  }
}
.carousel-item-b8e4c3 {
  position: absolute;
  width: 180px;
  height: 180px;
  left: 50%;
  top: 50%;
  margin-left: -90px;
  margin-top: -90px;
  background: linear-gradient(135deg, #667eea, #764ba2);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 48px;
  font-weight: bold;
  color: white;
  border-radius: 12px;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
  transform: rotateY(calc(var(--i) * 60deg)) translateZ(250px);
  opacity: 0.9;
}
</style>

# 4.4 悬浮效果

创造立体的悬浮效果:

<html>
  <div class="hover-3d-demo-b8e4c3">
    <div class="hover-card-b8e4c3">
      <div class="card-content-b8e4c3">
        <h3>3D悬浮卡片</h3>
        <p>移动鼠标查看效果</p>
      </div>
    </div>
  </div>
</html>
<script>
(function() {
  const card = document.querySelector('.hover-card-b8e4c3');
  if (!card) return;
  
  card.addEventListener('mousemove', function(e) {
    const rect = card.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;
    
    const centerX = rect.width / 2;
    const centerY = rect.height / 2;
    
    const rotateX = (y - centerY) / 10;
    const rotateY = (centerX - x) / 10;
    
    card.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(1.05)`;
  });
  
  card.addEventListener('mouseleave', function() {
    card.style.transform = 'perspective(1000px) rotateX(0deg) rotateY(0deg) scale(1)';
  });
})();
</script>
<style>
.hover-3d-demo-b8e4c3 {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 80px 20px;
}
.hover-card-b8e4c3 {
  width: 300px;
  height: 200px;
  background: linear-gradient(135deg, #667eea, #764ba2);
  border-radius: 16px;
  transition: transform 0.1s ease;
  cursor: pointer;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}
.card-content-b8e4c3 {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: white;
  padding: 20px;
  box-sizing: border-box;
}
.card-content-b8e4c3 h3 {
  margin: 0 0 10px 0;
  font-size: 24px;
}
.card-content-b8e4c3 p {
  margin: 0;
  opacity: 0.9;
  text-align: center;
}
</style>

# 五、性能优化与最佳实践

# 5.1 性能考虑

# 硬件加速

Transform会触发GPU加速,性能优秀:

/* ✅ 使用transform实现动画(GPU加速) */
.element {
  transform: translateX(100px);
  transition: transform 0.3s;
}

/* ❌ 避免使用left/top实现动画(CPU渲染) */
.element {
  left: 100px;
  transition: left 0.3s;
}

# Will-Change

提前告知浏览器哪些属性会变化:

.animated-element {
  will-change: transform;
}

/* 动画结束后移除 */
.animated-element.done {
  will-change: auto;
}

# 避免重排和重绘

/* ✅ 只触发合成 */
transform: translate3d(0, 0, 0);
opacity: 0.5;

/* ❌ 触发重排 */
width: 100px;
height: 100px;
margin: 10px;

# 5.2 浏览器兼容性

# Transform兼容性

现代浏览器都很好地支持transform:

/* 添加浏览器前缀以支持旧版本 */
.element {
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  transform: rotate(45deg);
}

# 3D Transform兼容性

/* 检测3D支持 */
@supports (transform: translate3d(0, 0, 0)) {
  .element {
    transform: translate3d(0, 0, 0);
  }
}

# 5.3 最佳实践

# 1. 合理使用Transform

/* ✅ 组合变换 */
.element {
  transform: translate(50px, 100px) rotate(45deg) scale(1.2);
}

/* ❌ 避免分开写(只有最后一个生效) */
.element {
  transform: translate(50px, 100px);
  transform: rotate(45deg);
  transform: scale(1.2);
}

# 2. 注意变换顺序

/* 不同的顺序产生不同的结果 */
transform: rotate(45deg) translateX(100px);
/* vs */
transform: translateX(100px) rotate(45deg);

# 3. 3D效果优化

/* ✅ 使用translate3d强制启用GPU加速 */
.element {
  transform: translate3d(0, 0, 0);
}

/* ✅ 设置perspective在父元素 */
.container {
  perspective: 1000px;
}

/* ✅ 使用transform-style保持3D */
.parent {
  transform-style: preserve-3d;
}

/* ✅ 隐藏背面 */
.card-face {
  backface-visibility: hidden;
}

# 4. 动画性能

/* ✅ 只动画transform和opacity */
.element {
  transition: transform 0.3s, opacity 0.3s;
}

/* ✅ 使用will-change提示浏览器 */
.element {
  will-change: transform;
}

/* ❌ 避免动画触发重排的属性 */
.element {
  transition: width 0.3s, height 0.3s, margin 0.3s;
}

# 5.4 调试技巧

# Chrome DevTools

  1. Layers面板:查看合成层
  2. Performance面板:分析动画性能
  3. Rendering面板:显示重绘区域

# 常见问题

/* 问题:元素变模糊 */
/* 解决:使用偶数值或translateZ强制GPU加速 */
.element {
  transform: translate3d(0, 0, 0);
}

/* 问题:3D效果不明显 */
/* 解决:增加perspective值 */
.container {
  perspective: 1000px; /* 增加到更大的值 */
}

/* 问题:子元素3D效果失效 */
/* 解决:设置transform-style */
.parent {
  transform-style: preserve-3d;
}

# 六、总结

CSS Transform是现代Web开发中不可或缺的工具:

2D变换要点:

  • translate:平移,用于位置调整和居中
  • rotate:旋转,创造旋转动画
  • scale:缩放,实现放大缩小效果
  • skew:倾斜,创造特殊视觉效果
  • 组合使用需注意顺序

3D变换要点:

  • perspective:设置透视距离
  • rotateX/Y/Z:3D旋转
  • translateZ:Z轴移动
  • transform-style: preserve-3d:保持3D空间
  • backface-visibility:控制背面可见性

性能优化:

  • Transform触发GPU加速,性能优秀
  • 使用 will-change 提前优化
  • 只动画 transform 和 opacity
  • 避免触发重排和重绘

实战应用:

  • 翻转卡片
  • 3D立方体
  • 旋转木马
  • 悬浮效果
  • 各种交互动画

通过本文的学习,你应该能够灵活运用2D和3D变换创造出丰富的视觉效果和交互体验,为你的网页增添更多动感和吸引力。

祝你变得更强!

编辑 (opens new window)
#CSS
上次更新: 2025/11/20
CSS进阶-渐变与阴影效果
CSS进阶-滤镜与混合模式

← CSS进阶-渐变与阴影效果 CSS进阶-滤镜与混合模式→

最近更新
01
AI编程时代的一些心得
09-11
02
Claude Code与Codex的协同工作
09-01
03
Claude Code 最佳实践(个人版)
08-01
更多文章>
Theme by Vdoing | Copyright © 2018-2025 京ICP备2021021832号-2 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式