# 2D Transforms
- A transform is an effect that lets an element change its shape, size and position
TIP
- Use this interactive example page to play with most of the properties and methods discussed below
- Note that you can double-click on a label to reset the related value
- The transform methods and transform-related properties are:
| methods and properties | description |
|---|---|
translate(unit ,[unit]),translateX(unit), translateY(unit) | move an element on the X and/or Y axis |
rotate(angle), rotateX(angle), rotateY(angle) | rotate an element around a fixed X, Y point |
scale(nr [, nr]), scaleX(nr), scaleY(nr) | scale an element along the X and/or Y axis |
skew(angle), skewX(angle), skewY(angle) | skew an element along the X and/or Y axis |
transform-origin: unit, unit | set the transformation point |
backface-visibility: visible | hidden | is the backface visible or not |
# translate()
- Move an element along the X and/or Y axis
- Positive arguments describe a move to the right/bottom
- Negative arguments move an element left/upwards
- You can use units like
px,rem,%, ... translate(arg)with one argument behaves exactly the same astranslateX(arg)
<h1>translate</h1>
<section>
<div>
<span>translate(20px)</span>
</div>
<div>
<span>translate(20px, -1rem)</span>
</div>
<div>
<span>translateX(20px)</span>
</div>
<div>
<span>translateY(1rem)</span>
</div>
</section>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 16px;
}
body {
font-family: Verdana, Geneva, sans-serif;
line-height: 1.5;
}
h1 {
font-size: 1rem;
margin: 1rem;
}
section {
display: flex;
flex-wrap: wrap;
}
div {
border: 1px solid darkgray;
background-color: rgba(169, 169, 169, .2);
display: inline-block;
margin: 1rem;
}
span {
display: inline-block;
width: 160px;
line-height: 160px;
font-size: .8rem;
text-align: center;
border: 1px solid #000;
background-color: rgba(248, 204, 52, .6);
}
div:nth-child(1) span {
transform: translate(20px);
}
div:nth-child(2) span {
transform: translate(20px, -1rem);
}
div:nth-child(3) span {
transform: translateX(20px);
}
div:nth-child(4) span {
transform: translateY(1rem);
}
| EMMET instruction | result | description |
|---|---|---|
trf:t + TAB | transform: translate(); | move an element on the X axis (and on the Y axis) |
trf:tx + TAB | transform: translateX(); | move an element on the X axis |
trf:ty + TAB | transform: translateY(); | move an element on the Y axis |
REMARK
The Emmet instructions mentioned above (and the transform-, transition- and animation-related Emmet instructions in the following chapters) produce some additional lines with vendor prefixes (-webkit-, -moz-, -ms- and/or -o-)
- In general, these lines may/should be deleted because all major browsers support transforms, transitions and animations
- Or, instead of using Emmet for these (less common) properties, you rely on the suggestions made by your code editor when you start typing
# rotate()
- Rotate an element around a fixed point (the default rotation point is
centeron both the X and Y axis)- Positive angles rotate clockwise
- Negative angles rotate counterclockwise
- The angle can be described as
deg(degrees),turn,rad(radians) orgrad(gradians)- The relationship between
degandturnis:
360deg=1turn,180deg=.5turn,45deg=.125turn,10deg=.028turn, ...
- The relationship between
<h1>rotate</h1>
<section>
<div>
<span>rotate(20deg)</span>
</div>
<div>
<span>rotateX(60deg)</span>
</div>
<div>
<span>rotateY(60deg)</span>
</div>
</section>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 16px;
}
body {
font-family: Verdana, Geneva, sans-serif;
line-height: 1.5;
}
h1 {
font-size: 1rem;
margin: 1rem;
}
section {
display: flex;
flex-wrap: wrap;
}
div {
border: 1px solid darkgray;
background-color: rgba(169, 169, 169, .2);
display: inline-block;
margin: 1rem;
}
span {
display: inline-block;
width: 150px;
line-height: 150px;
font-size: .9rem;
text-align: center;
border: 1px solid #000;
background-color: rgba(248, 204, 52, .6);
}
div:nth-child(1) span {
transform: rotate(20deg);
}
div:nth-child(2) span {
transform: rotateX(60deg);
}
div:nth-child(3) span {
transform: rotateY(60deg);
}
REMARK
Notice that in a 2D plane, rotateX() and rotateY() result in a squeezed element
| EMMET instruction | result | description |
|---|---|---|
trf:r + TAB | transform: rotate(); | rotate an element around a fixed point |
trf:rx + TAB | transform: rotateX(); | rotate an element horizontally around a fixed point |
trf:ry + TAB | transform: rotateY(); | rotate an element vertically around a fixed point |
CHROME TIP
- Open the CodePen in full screen
- Open DevTools and select the second
spantag - Double click on the angle of
rotateX() - Use the mousewheel or arrow keys to increment/decrement the value

# scale()
- Scale or "zoom" an element along the X and/or Y axis
- Arguments larger than 1 correspond to zooming in
- Arguments smaller than 1 will zoom out
scale(arg)with one argument scales along both the X and Y axis, i.e., it behaves asscaleX(arg)ANDscaleY(arg)
<h1>scale</h1>
<section>
<div>
<span>scale(1.2)</span>
</div>
<div>
<span>scale(1.2, .8)</span>
</div>
<div>
<span>scaleX(1.2)</span>
</div>
<div>
<span>scaleY(.8)</span>
</div>
</section>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 16px;
}
body {
font-family: Verdana, Geneva, sans-serif;
line-height: 1.5;
}
h1 {
font-size: 1rem;
margin: 1rem;
}
section {
display: flex;
flex-wrap: wrap;
}
div {
border: 1px solid darkgray;
background-color: rgba(169, 169, 169, .2);
display: inline-block;
margin: 2rem;
}
span {
display: inline-block;
width: 150px;
line-height: 150px;
font-size: .9rem;
text-align: center;
border: 1px solid #000;
background-color: rgba(248, 204, 52, .6);
}
div:nth-child(1) span {
transform: scale(1.2);
}
div:nth-child(2) span {
transform: scale(1.2, .8);
}
div:nth-child(3) span {
transform: scaleX(1.2);
}
div:nth-child(4) span {
transform: scaleY(.8);
}
| EMMET instruction | result | description |
|---|---|---|
trf:sc + TAB | transform: scale(); | scale an element along the X axis (and along the Y axis) |
trf:scx + TAB | transform: scaleX(); | scale an element along the X axis |
trf:scy + TAB | transform: scaleY(); | scale an element along the Y axis |
# skew()
- Skew an element along the X and/or Y axis
- The angle can be described as
deg,turn,radorgrad skew(angle)with only one angle behaves exactly the same asskewX(angle)
<h1>skew</h1>
<section>
<div>
<span>skew(20deg)</span>
</div>
<div>
<span>skew(20deg, 20deg)</span>
</div>
<div>
<span>skewX(20deg)</span>
</div>
<div>
<span>skewY(20deg)</span>
</div>
</section>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 16px;
}
body {
font-family: Verdana, Geneva, sans-serif;
line-height: 1.5;
}
h1 {
font-size: 1rem;
margin: 1rem;
}
section {
display: flex;
flex-wrap: wrap;
}
div {
border: 1px solid darkgray;
background-color: rgba(169, 169, 169, .2);
display: inline-block;
margin: 2rem;
}
span {
display: inline-block;
width: 150px;
line-height: 150px;
font-size: .8rem;
text-align: center;
border: 1px solid #000;
background-color: rgba(248, 204, 52, .6);
}
div:nth-child(1) span {
transform: skew(20deg);
}
div:nth-child(2) span {
transform: skew(20deg, 20deg);
}
div:nth-child(3) span {
transform: skewX(20deg);
}
div:nth-child(4) span {
transform: skewY(20deg);
}
| EMMET instruction | result | description |
|---|---|---|
transform: skew(); | skew an element along the X axis (and along the Y axis) | |
trf:skx + TAB | transform: skewX(); | skew an element along the X axis |
trf:sky + TAB | transform: skewY(); | skew an element along the Y axis |
# Combining methods
- You can combine two or more transform methods by separating them with a space
REMARK: ORDER MATTERS!
- Image on the left:
transform: rotate(45deg) translateX(70px)means:
firstrotate(45deg), thentranslateX(70px)the already rotated element - Image on the right:
transform: translateX(70px) rotate(45deg)means:
firsttranslateX(70px), thenrotate(45deg)the already translated element
# transform-origin
- Until now, our transformations took place around the default reference or transformation point, which is the center of the element
- The
transform-origin: x yproperty can change this transformation point - Possible values are:
top,center,bottom,leftorright- units like
px,%rem, ...
- In the example below, all blocks rotate by
10degbut the rotation is not immediately visible as the rotation takes place on the:hoverstate:- First block: no value for
transform-origin(default istransform-origin: center center) - Second block:
transform-origin: left top - Third block:
transform-origin: right bottom - Last block:
transform-origin: 15% 45%
- First block: no value for
<h1>transform-origin (on hover)</h1>
<section>
<div>
<span>center center</span>
</div>
<div>
<span>left top</span>
</div>
<div>
<span>right bottom</span>
</div>
<div>
<span>15% 45%</span>
</div>
</section>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 16px;
}
body {
font-family: Verdana, Geneva, sans-serif;
line-height: 1.5;
}
h1 {
font-size: 1rem;
margin: 1rem;
}
section {
display: flex;
flex-wrap: wrap;
}
div {
border: 1px solid darkgray;
background-color: rgba(169, 169, 169, .2);
display: inline-block;
margin: 2rem;
}
span {
display: inline-block;
width: 150px;
line-height: 150px;
font-size: .9rem;
text-align: center;
border: 1px solid #000;
background-color: rgba(248, 204, 52, .6);
}
div:nth-child(1):hover span {
transform: rotate(10deg);
}
div:nth-child(2):hover span {
transform: rotate(10deg);
transform-origin: left top;
}
div:nth-child(3):hover span {
transform: rotate(10deg);
transform-origin: right bottom;
}
div:nth-child(4):hover span {
transform: rotate(10deg);
transform-origin: 15% 45%;
}
| EMMET instruction | result | description |
|---|---|---|
trfo + TAB | transform-origin: ; | set the transformation point |
# backface-visibility
- When you rotate an element between
90degand270degaround the X and/or Y axis, the backface is by defaultvisibleand the content is shown in mirror image - You can easily hide (the backface of an) element with the property
backface-visibility: hidden; - In the example below:
- Change the
transformY()angle to a value between0and360deg - Angle between
0...90degor between270deg...360deg: bothspantags are visible - Angle between
90deg...270deg: the secondspantag ishidden
- Change the
span {
...
transform: rotateY(45deg); /* change value between 0 and 360deg */
}
div:nth-child(2) span {
backface-visibility: hidden; /* hidden between 90deg and 270deg */
}
1
2
3
4
5
6
7
2
3
4
5
6
7
<h1>backface-visibility</h1>
<section>
<div>
<span>Backface is visible</span>
</div>
<div>
<span>Backface is hidden</span>
</div>
</section>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 16px;
}
body {
font-family: Verdana, Geneva, sans-serif;
line-height: 1.5;
}
h1 {
font-size: 1rem;
margin: 1rem;
}
section {
display: flex;
flex-wrap: wrap;
}
div {
border: 1px solid darkgray;
background-color: rgba(169, 169, 169, .2);
display: inline-block;
margin: 2rem;
}
span {
display: inline-block;
width: 150px;
line-height: 300px;
font-size: .8rem;
text-align: center;
border: 1px solid #000;
background-color: rgba(248, 204, 52, .6);
transform: rotateY(45deg); /* change value between 0 and 360deg */
}
div:nth-child(2) span {
backface-visibility: hidden; /* hidden between 90deg and 270deg */
}
| EMMET instruction | result | description |
|---|---|---|
bfv:h + TAB | backface-visibility: hidden; | the backface of an element is not visible |
bfv:v + TAB | backface-visibility: visible; | the backface of an element is visible |