← CSS top 属性详解 CSS transition-delay 属性 →

CSS transform-origin 属性

原创 2025-09-09 CSS 已有人查阅

CSS transform-origin 属性详解与应用指南

概述与定义

CSS transform-origin 属性用于指定元素变换的原点位置,即变换操作(如旋转、缩放、倾斜等)的基准点。该属性必须与 transform 属性配合使用,可以应用于2D和变换场景。

通过调整变换原点,开发者可以创建出更加自然和符合预期的变换效果,为网页动画和交互设计提供更精细的控制能力。

基本语法与属性值

selector {
  transform-origin: x-axis y-axis z-axis | initial | inherit;
}

属性值说明

  • x-axis:定义水平方向的原点位置,可选值:length、percentage、left、center、right

  • y-axis:定义垂直方向的原点位置,可选值:length、percentage、top、center、bottom

  • z-axis:定义变换的Z轴原点位置,仅支持length值(不能使用百分比)

  • initial:将属性重置为默认值(50% 50%)

  • inherit:继承父元素的对应属性值

基础应用示例

1. 单值语法应用

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>transform-origin单值语法 - 代码号编程学习</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            min-height: 100vh;
            background-color: #f5f7fa;
            margin: 0;
            padding: 20px;
        }
        
        .example-container {
            display: flex;
            flex-wrap: wrap;
            gap: 30px;
            justify-content: center;
            max-width: 1000px;
            margin-top: 30px;
        }
        
        .transform-box {
            width: 150px;
            height: 150px;
            background: linear-gradient(45deg, #3498db, #2980b9);
            border-radius: 8px;
            display: flex;
            justify-content: center;
            align-items: center;
            color: white;
            font-weight: bold;
            transition: transform 0.5s ease;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
        }
        
        .transform-box:hover {
            transform: rotate(45deg);
        }
        
        .origin-left:hover {
            transform-origin: left;
        }
        
        .origin-right:hover {
            transform-origin: right;
        }
        
        .origin-top:hover {
            transform-origin: top;
        }
        
        .origin-bottom:hover {
            transform-origin: bottom;
        }
        
        .origin-center:hover {
            transform-origin: center;
        }
        
        .origin-50px:hover {
            transform-origin: 50px;
        }
        
        .origin-30per:hover {
            transform-origin: 30%;
        }
        
        .label {
            text-align: center;
            margin-top: 10px;
            font-weight: 500;
            color: #2c3e50;
            width: 150px;
        }
        
        h2 {
            color: #2c3e50;
            text-align: center;
        }
    </style>
</head>
<body>
    <h2>CSS transform-origin 单值语法示例</h2>
    
    <div class="example-container">
        <div>
            <div class="transform-box origin-left">左原点</div>
            <div class="label">transform-origin: left;</div>
        </div>
        
        <div>
            <div class="transform-box origin-right">右原点</div>
            <div class="label">transform-origin: right;</div>
        </div>
        
        <div>
            <div class="transform-box origin-top">上原点</div>
            <div class="label">transform-origin: top;</div>
        </div>
        
        <div>
            <div class="transform-box origin-bottom">下原点</div>
            <div class="label">transform-origin: bottom;</div>
        </div>
        
        <div>
            <div class="transform-box origin-center">中心原点</div>
            <div class="label">transform-origin: center;</div>
        </div>
        
        <div>
            <div class="transform-box origin-50px">50px原点</div>
            <div class="label">transform-origin: 50px;</div>
        </div>
        
        <div>
            <div class="transform-box origin-30per">30%原点</div>
            <div class="label">transform-origin: 30%;</div>
        </div>
    </div>
</body>
</html>

2. 双值语法应用

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>transform-origin双值语法 - 代码号教程</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            min-height: 100vh;
            background-color: #ecf0f1;
            margin: 0;
            padding: 20px;
        }
        
        .example-container {
            display: flex;
            flex-wrap: wrap;
            gap: 40px;
            justify-content: center;
            max-width: 1000px;
            margin-top: 30px;
        }
        
        .card {
            width: 180px;
            height: 180px;
            background: linear-gradient(135deg, #e74c3c, #c0392b);
            border-radius: 10px;
            display: flex;
            justify-content: center;
            align-items: center;
            color: white;
            font-weight: bold;
            transition: transform 0.4s ease;
            box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
        }
        
        .card:hover {
            transform: rotate(60deg);
        }
        
        .origin-left-top:hover {
            transform-origin: left top;
        }
        
        .origin-right-bottom:hover {
            transform-origin: right bottom;
        }
        
        .origin-center-center:hover {
            transform-origin: center center;
        }
        
        .origin-20px-40px:hover {
            transform-origin: 20px 40px;
        }
        
        .origin-30per-70per:hover {
            transform-origin: 30% 70%;
        }
        
        .origin-left-40px:hover {
            transform-origin: left 40px;
        }
        
        .origin-50px-top:hover {
            transform-origin: 50px top;
        }
        
        .code-sample {
            background-color: #2c3e50;
            color: #ecf0f1;
            padding: 12px;
            border-radius: 5px;
            font-family: monospace;
            margin-top: 15px;
            font-size: 14px;
            width: 180px;
        }
        
        h2 {
            color: #2c3e50;
            text-align: center;
        }
    </style>
</head>
<body>
    <h2>CSS transform-origin 双值语法示例</h2>
    
    <div class="example-container">
        <div>
            <div class="card origin-left-top">左上原点</div>
            <div class="code-sample">
                transform-origin:<br>
                left top;
            </div>
        </div>
        
        <div>
            <div class="card origin-right-bottom">右下原点</div>
            <div class="code-sample">
                transform-origin:<br>
                right bottom;
            </div>
        </div>
        
        <div>
            <div class="card origin-center-center">中心原点</div>
            <div class="code-sample">
                transform-origin:<br>
                center center;
            </div>
        </div>
        
        <div>
            <div class="card origin-20px-40px">20px 40px</div>
            <div class="code-sample">
                transform-origin:<br>
                20px 40px;
            </div>
        </div>
        
        <div>
            <div class="card origin-30per-70per">30% 70%</div>
            <div class="code-sample">
                transform-origin:<br>
                30% 70%;
            </div>
        </div>
        
        <div>
            <div class="card origin-left-40px">left 40px</div>
            <div class="code-sample">
                transform-origin:<br>
                left 40px;
            </div>
        </div>
        
        <div>
            <div class="card origin-50px-top">50px top</div>
            <div class="code-sample">
                transform-origin:<br>
                50px top;
            </div>
        </div>
    </div>
</body>
</html>

高级应用示例

1. 时钟指针动画效果

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>时钟指针动画 - 代码号学习示例</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
            background-color: #34495e;
            margin: 0;
            color: white;
        }
        
        .clock {
            width: 300px;
            height: 300px;
            border: 10px solid #ecf0f1;
            border-radius: 50%;
            position: relative;
            background: radial-gradient(circle, #2c3e50 10%, #34495e 65%);
            box-shadow: 0 0 30px rgba(0, 0, 0, 0.5);
        }
        
        .hour-hand, .minute-hand, .second-hand {
            position: absolute;
            transform-origin: bottom center;
            left: calc(50% - 3px);
            bottom: 50%;
        }
        
        .hour-hand {
            width: 6px;
            height: 70px;
            background-color: #e74c3c;
            border-radius: 3px 3px 0 0;
            animation: rotate-hour 43200s infinite linear;
        }
        
        .minute-hand {
            width: 4px;
            height: 100px;
            background-color: #3498db;
            border-radius: 2px 2px 0 0;
            animation: rotate-minute 3600s infinite linear;
        }
        
        .second-hand {
            width: 2px;
            height: 120px;
            background-color: #f1c40f;
            border-radius: 1px 1px 0 0;
            animation: rotate-second 60s infinite linear;
        }
        
        .center-point {
            position: absolute;
            width: 12px;
            height: 12px;
            background-color: #ecf0f1;
            border-radius: 50%;
            top: calc(50% - 6px);
            left: calc(50% - 6px);
            z-index: 10;
        }
        
        @keyframes rotate-hour {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
        }
        
        @keyframes rotate-minute {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
        }
        
        @keyframes rotate-second {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
        }
        
        .clock-mark {
            position: absolute;
            width: 4px;
            height: 12px;
            background-color: #ecf0f1;
            left: calc(50% - 2px);
            bottom: calc(100% - 20px);
            transform-origin: bottom center;
        }
        
        .mark-3 { transform: rotate(90deg); }
        .mark-6 { transform: rotate(180deg); }
        .mark-9 { transform: rotate(270deg); }
        
        h2 {
            margin-bottom: 30px;
            text-align: center;
        }
        
        .code-explanation {
            max-width: 600px;
            margin-top: 40px;
            padding: 20px;
            background-color: #2c3e50;
            border-radius: 8px;
            line-height: 1.6;
        }
    </style>
</head>
<body>
    <h2>CSS transform-origin 时钟指针动画示例</h2>
    
    <div class="clock">
        <div class="hour-hand"></div>
        <div class="minute-hand"></div>
        <div class="second-hand"></div>
        <div class="center-point"></div>
        
        <div class="clock-mark"></div>
        <div class="clock-mark mark-3"></div>
        <div class="clock-mark mark-6"></div>
        <div class="clock-mark mark-9"></div>
    </div>
    
    <div class="code-explanation">
        <h3>实现原理:</h3>
        <p>通过为时钟指针设置 <code>transform-origin: bottom center;</code> 将变换原点定位在指针底部中心,然后使用CSS动画实现旋转效果。</p>
        <p>时针、分针和秒针分别设置不同的旋转周期,模拟真实时钟的运行效果。</p>
    </div>
</body>
</html>

2. 立方体变换效果

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>立方体变换 - 代码号编程示例</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            margin: 0;
            perspective: 1000px;
        }
        
        .scene {
            width: 200px;
            height: 200px;
            perspective: 600px;
            margin: 50px auto;
        }
        
        .cube {
            width: 100%;
            height: 100%;
            position: relative;
            transform-style: preserve-3d;
            transform: translateZ(-100px);
            transition: transform 1s;
        }
        
        .cube-face {
            position: absolute;
            width: 200px;
            height: 200px;
            border: 2px solid white;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 24px;
            font-weight: bold;
            color: white;
            background: rgba(52, 152, 219, 0.8);
            backface-visibility: visible;
        }
        
        .front {
            transform: rotateY(0deg) translateZ(100px);
            background: rgba(231, 76, 60, 0.8);
        }
        
        .back {
            transform: rotateY(180deg) translateZ(100px);
            background: rgba(46, 204, 113, 0.8);
        }
        
        .right {
            transform: rotateY(90deg) translateZ(100px);
            background: rgba(155, 89, 182, 0.8);
        }
        
        .left {
            transform: rotateY(-90deg) translateZ(100px);
            background: rgba(241, 196, 15, 0.8);
        }
        
        .top {
            transform: rotateX(90deg) translateZ(100px);
            background: rgba(52, 152, 219, 0.8);
        }
        
        .bottom {
            transform: rotateX(-90deg) translateZ(100px);
            background: rgba(230, 126, 34, 0.8);
        }
        
        .controls {
            margin-top: 30px;
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
            justify-content: center;
            max-width: 500px;
        }
        
        .control-btn {
            padding: 10px 15px;
            background-color: #2c3e50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: background-color 0.3s;
        }
        
        .control-btn:hover {
            background-color: #1a252f;
        }
        
        .origin-controls {
            margin-top: 20px;
            display: flex;
            flex-direction: column;
            gap: 10px;
            background-color: rgba(44, 62, 80, 0.8);
            padding: 15px;
            border-radius: 8px;
            width: 300px;
        }
        
        .origin-slider {
            width: 100%;
        }
        
        h2 {
            color: white;
            text-align: center;
            margin-bottom: 10px;
        }
        
        .explanation {
            color: white;
            max-width: 600px;
            margin-top: 30px;
            text-align: center;
            line-height: 1.6;
        }
    </style>
</head>
<body>
    <h2>立方体与transform-origin应用</h2>
    
    <div class="scene">
        <div class="cube" id="cube">
            <div class="cube-face front">前面</div>
            <div class="cube-face back">后面</div>
            <div class="cube-face right">右面</div>
            <div class="cube-face left">左面</div>
            <div class="cube-face top">上面</div>
            <div class="cube-face bottom">下面</div>
        </div>
    </div>
    
    <div class="controls">
        <button class="control-btn" onclick="rotateCube('rotateX', 90)">绕X轴旋转</button>
        <button class="control-btn" onclick="rotateCube('rotateY', 90)">绕Y轴旋转</button>
        <button class="control-btn" onclick="rotateCube('rotateZ', 90)">绕Z轴旋转</button>
        <button class="control-btn" onclick="resetCube()">重置立方体</button>
    </div>
    
    <div class="origin-controls">
        <h3>变换原点控制</h3>
        <label>
            X轴: <input type="range" class="origin-slider" id="x-origin" min="0" max="200" value="100" oninput="updateOrigin()">
            <span id="x-value">100px</span>
        </label>
        <label>
            Y轴: <input type="range" class="origin-slider" id="y-origin" min="0" max="200" value="100" oninput="updateOrigin()">
            <span id="y-value">100px</span>
        </label>
        <label>
            Z轴: <input type="range" class="origin-slider" id="z-origin" min="-200" max="200" value="0" oninput="updateOrigin()">
            <span id="z-value">0px</span>
        </label>
    </div>
    
    <div class="explanation">
        <p>此示例演示了立方体的创建和transform-origin属性的应用。通过调整变换原点,可以改变立方体旋转的基准点。</p>
        <p>使用滑块可以实时调整X、Y、Z轴的变换原点位置,观察不同原点对立方体旋转效果的影响。</p>
    </div>

    <script>
        const cube = document.getElementById('cube');
        let currentRotation = { x: 0, y: 0, z: 0 };
        
        function rotateCube(axis, degrees) {
            if (axis === 'rotateX') currentRotation.x += degrees;
            if (axis === 'rotateY') currentRotation.y += degrees;
            if (axis === 'rotateZ') currentRotation.z += degrees;
            
            cube.style.transform = `translateZ(-100px) rotateX(${currentRotation.x}deg) rotateY(${currentRotation.y}deg) rotateZ(${currentRotation.z}deg)`;
        }
        
        function resetCube() {
            currentRotation = { x: 0, y: 0, z: 0 };
            cube.style.transform = 'translateZ(-100px)';
            document.getElementById('x-origin').value = 100;
            document.getElementById('y-origin').value = 100;
            document.getElementById('z-origin').value = 0;
            document.getElementById('x-value').textContent = '100px';
            document.getElementById('y-value').textContent = '100px';
            document.getElementById('z-value').textContent = '0px';
            cube.style.transformOrigin = '100px 100px 0px';
        }
        
        function updateOrigin() {
            const x = document.getElementById('x-origin').value;
            const y = document.getElementById('y-origin').value;
            const z = document.getElementById('z-origin').value;
            
            document.getElementById('x-value').textContent = x + 'px';
            document.getElementById('y-value').textContent = y + 'px';
            document.getElementById('z-value').textContent = z + 'px';
            
            cube.style.transformOrigin = `${x}px ${y}px ${z}px`;
        }
    </script>
</body>
</html>

性能优化与实践

1. 硬件加速优化

.element {
  transform: translateZ(0); /* 启用GPU加速 */
  transform-origin: center center;
  will-change: transform; /* 提示浏览器元素将要变换 */
}

2. 合理使用变换原点


/* 对于旋转动画,将原点设置在元素边缘 */
.spinner {
  transform-origin: center center;
  animation: spin 2s infinite linear;
}

/* 对于缩放动画,将原点设置在变换起点 */
.zoomer {
  transform-origin: top left;
  transition: transform 0.3s ease;
}

.zoomer:hover {
  transform: scale(1.2);
}

本节课程知识要点

  1. 变换原点概念:transform-origin属性定义了元素变换的基准点

  2. 值类型:支持长度值、百分比值和关键字(left、right、top、bottom、center)

  3. 语法格式:支持单值、双值和三值语法,分别对应不同维度的变换

  4. 变换支持:Z轴值仅支持长度单位,不能使用百分比

  5. 默认值:transform-origin的默认值为50% 50%(元素中心)

  6. 应用场景:适用于旋转、缩放、倾斜等各种变换操作

  7. 性能考虑:合理使用变换原点可以提高动画性能和视觉效果

实际应用场景

  1. 旋转动画:将变换原点设置在元素边缘创建钟摆效果

  2. 缩放效果:将变换原点设置在鼠标位置实现定向缩放

  3. 变换:在场景中精确定义变换基准点

  4. 菜单动画:将变换原点设置在菜单边缘创建展开/收起效果

  5. 卡片翻转:配合perspective属性创建卡片翻转效果

  6. 加载动画:创建各种风格的加载动画和进度指示器

← CSS top 属性详解 CSS transition-delay 属性 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号