By modifying the coordinate space, CSS transforms change the shape and position of the affected content without disrupting the normal document flow. This guide provides an introduction to using transforms.
CSS transforms are implemented using a set of CSS properties that let you apply affine linear transformations to HTML elements. These transformations include rotation, skewing, scaling, and translation both in the plane and in the 3D space.
Only elements positioned by the box model can be transform
ed. As a rule of thumb, an element is positioned by the box model if it has display: block
.
Two major properties are used to define CSS transforms: transform
and transform-origin
transform-origin
transform
Here is an unaltered image of the MDN logo:
Here is the MDN logo in an iframe, rotated 90 degrees from its bottom-left corner.
<img style="transform: rotate(90deg); transform-origin: bottom left;" src="https://mdn.mozillademos.org/files/12539/Screen%20Shot%202016-02-16%20at%2015.53.54.png">
Here is the MDN logo, skewed by 10 degrees and translated by 150 pixels on the X axis.
<img style="transform: skewx(10deg) translatex(150px); transform-origin: bottom left;" src="https://mdn.mozillademos.org/files/12539/Screen%20Shot%202016-02-16%20at%2015.53.54.png">
Performing CSS transformations in 3D space is a bit more complex. You have to start by configuring the 3D space by giving it a perspective, then you have to configure how your 2D elements will behave in that space.
The first element to set is the perspective
. The perspective is what gives us the 3D impression. The farther from the viewer the elements are, the smaller they are.
This example shows a cube with the perspective set at different positions. How quick the cube shrinks is defined by the perspective
property. The smaller its value is, the deeper the perspective is.
The HTML below creates four copies of the same box, with the perspective set at different values.
<table> <tbody> <tr> <th><code>perspective: 250px;</code> </th> <th><code>perspective: 350px;</code> </th> </tr> <tr> <td> <div class="container"> <div class="cube pers250"> <div class="face front">1</div> <div class="face back">2</div> <div class="face right">3</div> <div class="face left">4</div> <div class="face top">5</div> <div class="face bottom">6</div> </div> </div> </td> <td> <div class="container"> <div class="cube pers350"> <div class="face front">1</div> <div class="face back">2</div> <div class="face right">3</div> <div class="face left">4</div> <div class="face top">5</div> <div class="face bottom">6</div> </div> </div> </td> </tr> <tr> <th><code>perspective: 500px;</code> </th> <th><code>perspective: 650px;</code> </th> </tr> <tr> <td> <div class="container"> <div class="cube pers500"> <div class="face front">1</div> <div class="face back">2</div> <div class="face right">3</div> <div class="face left">4</div> <div class="face top">5</div> <div class="face bottom">6</div> </div> </div> </td> <td> <div class="container"> <div class="cube pers650"> <div class="face front">1</div> <div class="face back">2</div> <div class="face right">3</div> <div class="face left">4</div> <div class="face top">5</div> <div class="face bottom">6</div> </div> </div> </td> </tr> </tbody> </table>
The CSS establishes classes that can be used to set the perspective to different distances. It also includes classes for the container box and the cube itself, as well as each of its faces.
/* Shorthand classes for different perspective values */ .pers250 { perspective: 250px; } .pers350 { perspective: 350px; } .pers500 { perspective: 500px; } .pers650 { perspective: 650px; } /* Define the container div, the cube div, and a generic face */ .container { width: 200px; height: 200px; margin: 75px 0 0 75px; border: none; } .cube { width: 100%; height: 100%; backface-visibility: visible; perspective-origin: 150% 150%; transform-style: preserve-3d; } .face { display: block; position: absolute; width: 100px; height: 100px; border: none; line-height: 100px; font-family: sans-serif; font-size: 60px; color: white; text-align: center; } /* Define each face based on direction */ .front { background: rgba(0, 0, 0, 0.3); transform: translateZ(50px); } .back { background: rgba(0, 255, 0, 1); color: black; transform: rotateY(180deg) translateZ(50px); } .right { background: rgba(196, 0, 0, 0.7); transform: rotateY(90deg) translateZ(50px); } .left { background: rgba(0, 0, 196, 0.7); transform: rotateY(-90deg) translateZ(50px); } .top { background: rgba(196, 196, 0, 0.7); transform: rotateX(90deg) translateZ(50px); } .bottom { background: rgba(196, 0, 196, 0.7); transform: rotateX(-90deg) translateZ(50px); } /* Make the table a little nicer */ th, p, td { background-color: #EEEEEE; padding: 10px; font-family: sans-serif; text-align: left; }
The second element to configure is the position of the viewer, with the perspective-origin
property. By default the perspective is centered on the viewer, which is not always adequate.
This example shows cubes with popular perspective-origin
values.
<table> <tbody> <tr> <th> <code>perspective-origin: top left;</code> </th> <th> <code>perspective-origin: top;</code> </th> <th> <code>perspective-origin: top right;</code> </th> </tr> <tr> <td> <div class="container"> <div class="cube potl"> <div class="face front">1</div> <div class="face back">2</div> <div class="face right">3</div> <div class="face left">4</div> <div class="face top">5</div> <div class="face bottom">6</div> </div> </div> </td> <td> <div class="container"> <div class="cube potm"> <div class="face front">1</div> <div class="face back">2</div> <div class="face right">3</div> <div class="face left">4</div> <div class="face top">5</div> <div class="face bottom">6</div> </div> </div> </td> <td> <div class="container"> <div class="cube potr"> <div class="face front">1</div> <div class="face back">2</div> <div class="face right">3</div> <div class="face left">4</div> <div class="face top">5</div> <div class="face bottom">6</div> </div> </div> </td> </tr> <tr> <th> <code>perspective-origin: left;</code> </th> <th> <code>perspective-origin: 50% 50%;</code> </th> <th> <code>perspective-origin: right;</code> </th> </tr> <tr> <td> <div class="container"> <div class="cube poml"> <div class="face front">1</div> <div class="face back">2</div> <div class="face right">3</div> <div class="face left">4</div> <div class="face top">5</div> <div class="face bottom">6</div> </div> </div> </td> <td> <div class="container"> <div class="cube pomm"> <div class="face front">1</div> <div class="face back">2</div> <div class="face right">3</div> <div class="face left">4</div> <div class="face top">5</div> <div class="face bottom">6</div> </div> </div> </td> <td> <div class="container"> <div class="cube pomr"> <div class="face front">1</div> <div class="face back">2</div> <div class="face right">3</div> <div class="face left">4</div> <div class="face top">5</div> <div class="face bottom">6</div> </div> </div> </td> </tr> <tr> <th> <code>perspective-origin: bottom left;</code> </th> <th> <code>perspective-origin: bottom;</code> </th> <th> <code>perspective-origin: bottom right;</code> </th> </tr> <tr> <td> <div class="container"> <div class="cube pobl"> <div class="face front">1</div> <div class="face back">2</div> <div class="face right">3</div> <div class="face left">4</div> <div class="face top">5</div> <div class="face bottom">6</div> </div> </div> </td> <td> <div class="container"> <div class="cube pobm"> <div class="face front">1</div> <div class="face back">2</div> <div class="face right">3</div> <div class="face left">4</div> <div class="face top">5</div> <div class="face bottom">6</div> </div> </div> </td> <td> <div class="container"> <div class="cube pobr"> <div class="face front">1</div> <div class="face back">2</div> <div class="face right">3</div> <div class="face left">4</div> <div class="face top">5</div> <div class="face bottom">6</div> </div> </div> </td> </tr> </tbody> </table>
/* Shorthand classes for perspective-origin values */ .potl { perspective-origin: top left; -webkit-perspective-origin: top left; } .potm { perspective-origin: top; -webkit-perspective-origin: top; } .potr { perspective-origin: top right; -webkit-perspective-origin: top right; } .poml { perspective-origin: left; -webkit-perspective-origin: left; } .pomm { perspective-origin: 50% 50%; -webkit-perspective-origin: 50% 50%; } .pomr { perspective-origin: right; -webkit-perspective-origin: right; } .pobl { perspective-origin: bottom left; -webkit-perspective-origin: bottom left; } .pobm { perspective-origin: bottom; -webkit-perspective-origin: bottom; } .pobr { perspective-origin: bottom right; -webkit-perspective-origin: bottom right; } /* Define the container div, the cube div, and a generic face */ .container { width: 100px; height: 100px; margin: 24px; border: none; } .cube { width: 100%; height: 100%; backface-visibility: visible; perspective: 300px; transform-style: preserve-3d; -webkit-backface-visibility: visible; -webkit-perspective: 300px; -webkit-transform-style: preserve-3d; } .face { display: block; position: absolute; width: 100px; height: 100px; border: none; line-height: 100px; font-family: sans-serif; font-size: 60px; color: white; text-align: center; } /* Define each face based on direction */ .front { background: rgba(0, 0, 0, 0.3); transform: translateZ(50px); -webkit-transform: translateZ(50px); } .back { background: rgba(0, 255, 0, 1); color: black; transform: rotateY(180deg) translateZ(50px); -webkit-transform: rotateY(180deg) translateZ(50px); } .right { background: rgba(196, 0, 0, 0.7); transform: rotateY(90deg) translateZ(50px); -webkit-transform: rotateY(90deg) translateZ(50px); } .left { background: rgba(0, 0, 196, 0.7); transform: rotateY(-90deg) translateZ(50px); -webkit-transform: rotateY(-90deg) translateZ(50px); } .top { background: rgba(196, 196, 0, 0.7); transform: rotateX(90deg) translateZ(50px); -webkit-transform: rotateX(90deg) translateZ(50px) } .bottom { background: rgba(196, 0, 196, 0.7); transform: rotateX(-90deg) translateZ(50px); -webkit-transform: rotateX(-90deg) translateZ(50px); } /* Make the table a little nicer */ th, p, td { background-color: #EEEEEE; padding: 10px; font-family: sans-serif; text-align: left; }
Once you have done this, you can work on the element in the 3D space.
© 2005–2018 Mozilla Developer Network and individual contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transforms/Using_CSS_transforms