# 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 as- translateX(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 as- scaleX(arg)AND- scaleY(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 as- skewX(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,- leftor- right
- 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 | 
