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>

四、浏览器兼容性

特性 Chrome Firefox Safari Edge IE
2D transform 36+ 16+ 9+ 12+ 10+
3D transform 36+ 16+ 9+ 12+ 10+
transform-origin 36+ 16+ 9+ 12+ 10+
transform-style: preserve-3d 36+ 16+ 9+ 12+ 11+
backface-visibility 36+ 16+ 9+ 12+ 10+
perspective 36+ 16+ 9+ 12+ 10+

五、注意事项与最佳实践

注意事项

  • 变换不影响文档流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导致文字模糊如何解决?

原因是非整数像素的 translatescale 导致亚像素渲染。使用整数值,或在动画结束后移除 transform,或添加 translateZ(0) 强制GPU渲染。

八、总结

CSS transform 是实现2D/3D变换的核心属性,支持 translate(平移)、rotate(旋转)、scale(缩放)、skew(倾斜)四大变换函数,以及对应的3D版本。变换不影响文档流,由GPU加速渲染,性能优异。在实际开发中,应优先使用 transform 代替定位属性做动画,注意变换顺序,合理使用 perspectivetransform-style: preserve-3d 创建3D效果。核心原则是:优先GPU加速、注意变换顺序、合理使用3D、不影响文档流

标签: CSS变换 transform 2D变换 3D变换 GPU加速 CSS动画 perspective

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: CSS集成:CSS动画详解 - @keyframes与animation属性完整指南 下一篇: CSS滤镜:filter属性与视觉效果 - 详细教程与指南

poll相关推荐