transform-origin CSS 属性让你更改一个元素变形的原点。
{{InteractiveExample("CSS Demo: transform-origin")}}
```css interactive-example-choice transform-origin: center;
```css interactive-example-choice
transform-origin: top left;
```css interactive-example-choice transform-origin: 50px 50px;
```css interactive-example-choice
/* 3D rotation with z-axis origin */
transform-origin: bottom right 60px;
```html interactive-example
```css interactive-example
@keyframes rotate {
from {
transform: rotate(0);
}
to {
transform: rotate(30deg);
}
}
@keyframes rotate3d {
from {
transform: rotate3d(0);
}
to {
transform: rotate3d(1, 2, 0, 60deg);
}
}
#example-container {
width: 160px;
height: 160px;
position: relative;
}
#example-element {
width: 100%;
height: 100%;
display: flex;
position: absolute;
align-items: center;
justify-content: center;
background: #f7ebee;
color: #000000;
font-size: 1.2rem;
text-transform: uppercase;
}
#example-element.rotate {
animation: rotate 1s forwards;
}
#example-element.rotate3d {
animation: rotate3d 1s forwards;
}
#crosshair {
width: 24px;
height: 24px;
opacity: 0;
position: absolute;
}
#static-element {
width: 100%;
height: 100%;
position: absolute;
border: dotted 3px #ff1100;
}
```js interactive-example "use strict";
window.addEventListener("load", () => { function update() { const selected = document.querySelector(".selected");
/* Restart the animation
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Tips */
el.className = "";
window.requestAnimationFrame(() => {
window.requestAnimationFrame(() => {
el.className =
el.style.transformOrigin.split(" ")[2] === "60px"
? "rotate3d"
: "rotate";
});
});
const transformOrigin = getComputedStyle(el).transformOrigin;
const pos = transformOrigin.split(/\s+/);
crosshair.style.left = `calc(${pos[0]} - 12px)`;
crosshair.style.top = `calc(${pos[1]} - 12px)`;
}
const crosshair = document.getElementById("crosshair"); const el = document.getElementById("example-element");
const observer = new MutationObserver(() => { update(); });
observer.observe(el, { attributes: true, attributeFilter: ["style"], });
update(); crosshair.style.opacity = "1"; });
转换起点是应用转换的点。例如,`rotate()`函数的转换原点是旋转中心。(这个属性的应用原理是先用这个属性的赋值转换该元素,进行变形,然后再用这个属性的值把元素转换回去)
默认的转换原点是 `center`
## 语法
```css
/* One-value syntax */
transform-origin: 2px;
transform-origin: bottom;
/* x-offset | y-offset */
transform-origin: 3cm 2px;
/* x-offset-keyword | y-offset */
transform-origin: left 2px;
/* x-offset-keyword | y-offset-keyword */
transform-origin: right top;
/* y-offset-keyword | x-offset-keyword */
transform-origin: top right;
/* x-offset | y-offset | z-offset */
transform-origin: 2px 30% 10px;
/* x-offset-keyword | y-offset | z-offset */
transform-origin: left 5px -3px;
/* x-offset-keyword | y-offset-keyword | z-offset */
transform-origin: right bottom 2cm;
/* y-offset-keyword | x-offset-keyword | z-offset */
transform-origin: bottom right 2cm;
/* Global values */
transform-origin: inherit;
transform-origin: initial;
transform-origin: unset;
transform-origin属性可以使用一个,两个或三个值来指定,其中每个值都表示一个偏移量。没有明确定义的偏移将重置为其对应的初始值。
如果定义了两个或更多值并且没有值的关键字,或者唯一使用的关键字是center,则第一个值表示水平偏移量,第二个值表示垂直偏移量。
一个值:
- 必须是{{cssxref("<length>")}},{{cssxref("<percentage>")}},或
left,center,right,top,bottom关键字中的一个。
- 必须是{{cssxref("<length>")}},{{cssxref("<percentage>")}},或
两个值:
- 其中一个必须是{{cssxref("<length>")}},{{cssxref("<percentage>")}},或
left,center,right关键字中的一个。 - 另一个必须是{{cssxref("<length>")}},{{cssxref("<percentage>")}},或
top,center,bottom关键字中的一个。
- 其中一个必须是{{cssxref("<length>")}},{{cssxref("<percentage>")}},或
三个值:
- 前两个值和只有两个值时的用法相同。
- 第三个值必须是{{cssxref("<length>")}}。它始终代表 Z 轴偏移量。
值
- x-offset
- : 定义变形中心距离盒模型的左侧的{{cssxref("<length>")}}或{{cssxref("<percentage>")}}偏移值。
- offset-keyword
- :
left,right,top,bottom或center中之一,定义相对应的变形中心偏移。
- :
- y-offset
- : 定义变形中心距离盒模型的顶的{{cssxref("<length>")}}或{{cssxref("<percentage>")}}偏移值。
- x-offset-keyword
- :
left,right或center中之一,定义相对应的变形中心偏移。
- :
- y-offset-keyword
- :
top,bottom或center中之一,定义相对应的变形中心偏移。
- :
- z-offset
- : 定义变形中心距离用户视线(z=0 处)的{{cssxref("<length>")}}(不能是{{cssxref("<percentage>")}})偏移值。
关键字是方便的简写方法,等同于以下{{cssxref("<percentage>")}}值:
| keyword | value |
|---|---|
left |
0% |
center |
50% |
right |
100% |
top |
0% |
bottom |
100% |
形式语法
{{csssyntax}}
示例
| Code | Sample |
|---|---|
|
|
<div class="box1"> </div>
.box1 {
margin: 0.5em;
width: 3em;
height: 3em;
border: solid 1px;
background-color: palegreen;
transform: none;
-webkit-transform: none;
}
{{EmbedLiveSample('transform_none', '', 120, '', '', 'no-button') }}
|
|
|
<div class="box2"> </div>
.box2 {
margin: 0.5em;
width: 3em;
height: 3em;
border: solid 1px;
background-color: palegreen;
transform: rotate(30deg);
-webkit-transform: rotate(30deg);
}
{{EmbedLiveSample('transform_rotate_only', '', 120, '', '', 'no-button') }}
|
|
|
<div class="box3"> </div>
.box3 {
margin: 0.5em;
width: 3em;
height: 3em;
border: solid 1px;
background-color: palegreen;
transform-origin: 0 0;
-webkit-transform-origin: 0 0;
transform: rotate(30deg);
-webkit-transform: rotate(30deg);
}
{{EmbedLiveSample('transform_rotate', '', 120, '', '', 'no-button') }}
|
|
|
<div class="box4"> </div>
.box4 {
margin: 0.5em;
width: 3em;
height: 3em;
border: solid 1px;
background-color: palegreen;
transform-origin: 100% 100%;
-webkit-transform-origin: 100% 100%;
transform: rotate(30deg);
-webkit-transform: rotate(30deg);
}
{{EmbedLiveSample('transform_rotate_with_percentage', '', 120, '', '', 'no-button') }}
|
|
|
<div class="box5"> </div>
.box5 {
margin: 0.5em;
width: 3em;
height: 3em;
border: solid 1px;
background-color: palegreen;
transform-origin: -1em -3em;
-webkit-transform-origin: -1em -3em;
transform: rotate(30deg);
-webkit-transform: rotate(30deg);
}
{{EmbedLiveSample('transform_rotate_with_em', '', 120, '', '', 'no-button') }}
|
|
|
<div class="box6"> </div>
.box6 {
margin: 0.5em;
width: 3em;
height: 3em;
border: solid 1px;
background-color: palegreen;
transform: scale(
{{EmbedLiveSample('transform_scale_only', '', 120, '', '', 'no-button') }}
|
|
|
<div class="box7"> </div>
.box7 {
margin: 0.5em;
width: 3em;
height: 3em;
border: solid 1px;
background-color: palegreen;
transform: scale(
{{EmbedLiveSample('transform_scale_without_origin', '', 120, '', '', 'no-button') }}
|
|
|
<div class="box8"> </div>
.box8 {
margin: 0.5em;
width: 3em;
height: 3em;
border: solid 1px;
background-color: palegreen;
transform: scale(
{{EmbedLiveSample('transform_scale', '', 120, '', '', 'no-button') }}
|
|
|
<div class="box9"> </div>
.box9 {
margin: 0.5em;
width: 3em;
height: 3em;
border: solid 1px;
background-color: palegreen;
transform: skewX(50deg);
-webkit-transform: skewX(50deg);
transform-origin: 100% -30%;
-webkit-transform-origin: 100% -30%;
}
{{EmbedLiveSample('transform_skew_x', '', 120, '', '', 'no-button') }}
|
|
|
<div class="box10"> </div>
.box10 {
margin: 0.5em;
width: 3em;
height: 3em;
border: solid 1px;
background-color: palegreen;
transform: skewY(50deg);
-webkit-transform: skewY(50deg);
transform-origin: 100% -30%;
-webkit-transform-origin: 100% -30%;
}
{{EmbedLiveSample('transform_skew_y', '', 120, '', '', 'no-button') }}
|