We draw inspiration for this tutorial from Envato’s latest initiative; Envato Elements. The homepage of Elements features a range of creative products (Fonts, Icons, Graphic Templates and so on) displaying them together on a neat isometric grid layout.

We are going to recreate this isometric landscape using CSS 3D Transforms.
Isometric Projection
“Isometric projection” is a method (commonly used in engineering and games in the 80s and 90s where 3D processing power was very limited) for presenting a design in apparent three dimensions.

These are not three dimensions as we experience them in real life–the plane on which they’re displayed is lacking perspective.
The Z-Axis
For many years, the web has been a two-dimensional environment and we are accustomed to positioning elements along two axes or directions: the x-axis (horizontal) and y-axis (vertical).
Note: the y-axis on the web is reversed contrary to the original Cartesian coordinate principle, since the web is read top to bottom.
The third axis, namely the z-axis, is required to project a 3D view. This axis represents depth, and the movement direction of an object along the z-axis is relative to our point of view; it may move top-bottom, up-down, or near-far.

These three axes can be applied to the CSS Transform function to create a 3D projection. In the following demo, we use the rotateX()
, rotateY()
, and rotateZ()
function to create an isometric projection of a rectangle:
Now that we have the basic principle that underlies an isometric projection, we can put it into practice. And we begin with the HTML.
HTML
Similarly to the Envato Elements homepage, we have a grid layout. Our grid comprises a row with nine columns. Each column contains a product image, the link pointing to the product page, and as you can see below, a span
element which we will use to model the image shadow.
<div class="row"><div class="column"><div class="ItemCard"><a class="ItemCard__dest cover" href="https://elements.envato.com/items/type/fonts/herbert-lemuel-GHH8KT" target="_blank"></a><figure class="ItemCard__thumb"><img src="./images/001.jpg" height="340" width="510" alt=""><span class="shadow cover"></span></figure></div></div><div class="column"><div class="ItemCard"><a class="ItemCard__dest cover" href="https://elements.envato.com/items/type/add-ons/roller-paint-brush-EZ9ZVZ" target="_blank"></a><figure class="ItemCard__thumb"><img src="./images/002.jpg" height="340" width="510" alt=""><span class="shadow cover"></span></figure></div></div><!-- 7 more items... --></div>
CSS
We begin begin with the row and the columns.
.row { width: 960px; display: flex; flex-wrap:wrap; justify-content:flex-end; transform-style:preserve-3d; transform: rotateX(60deg) rotateY(0deg) rotateZ(-45deg); } .column { padding:20px; width:50%; max-width: 50%; flex: 1 1 50%; }
The above styles set the row to display: flex
, set the transform styles to 3D so the browsers will adhere to the z-axis transformation correctly, rotate the row to create an isometric view, and lastly divide the columns within the row into half.

Next, we add styles to the .cover
class, which we’ve added to the product link anchor tag, and the span
element (soon to be the shadow).
.cover { position:absolute; top:0; left:0; width:100%; height:100%; }
Having this style added, the product link as well as the span
element now stretch all the way across the container. We are also able to change the element stack position later on.
Image Styles
The following styles govern the image wrapper element position, padding, and some 3D stuff. The backface-visibility
is set so we won’t see through the stack underneath the translated or rotated element, and won’t see the inverted face of the image.
We apply transition to the image, and move through the z-axis to make it “levitate” above the shadow by 15px
. Similarly, we also add some 3D stuff: backface-visibility
and transform-style
, so it will render the 3D view properly.
.ItemCard__thumb { position:relative; padding:0; backface-visibility:hidden; transform-style:preserve-3d; } .ItemCard__thumb img { display:block; cursor: pointer; transition:transform .3s cubic-bezier(.165, .84, .44, 1); transform:translate3d(0,0,15px); border-radius:6px; backface-visibility:hidden; transform-style:preserve-3d; }
Shadow Styles
The following gives us our shadow styles. The shadow spread should be narrow and the shadow shade darker since the image, at this point, is closer (by 15px
) to the “floor” where the shadow is reflected.
.shadow { display:block; transition:all .3s cubic-bezier(.165, .84, .44, 1); border-radius:6px; opacity:.9; background-color:rgba(0,0,0,.12); box-shadow:0 0 5px 1px rgba(0,0,0,.12); }
We have made quite some progress:

Hover Effect
The hover effect will make each image thumbnail more engaging.
.column:hover .ItemCard__dest, .column:hover .ItemCard__thumb { z-index: 10; } .column:hover .ItemCard__dest, .column:hover .ItemCard__thumb img { transform: translate3d(0, 0, 50px) rotateX(-5deg); transform-origin: center bottom; } .column:hover .ItemCard__thumb .shadow { opacity: .6; background-color: rgba(0, 0, 0, 0.1); box-shadow: 0 0 10px 6px rgba(0, 0, 0, 0.1); }
In the hover state, as shown in the above code snippet, we will first move the element stack up higher, so the image (and the link) will appear above the rest of the items within the grid.
We will also lift the image slightly; moving it away from the “floor” and a bit closer to the “light” source. This being said the shadow should lose some clarity, so we decrease the shadow opacity.

Wrapping Up
In this tutorial, we have used 3D transforms in CSS to build a replica of Envato Elements’ isometric grid. We also learned how to add realism in terms of shadows and light sources. Take a look at the demo, grab the source files, and let us know what you do with them!
3D Transforms are a powerful CSS utility. But don’t consider them merely a gimmick or a toy for adding a fancy layer to the web. If applied thoughtfully, 3D elements can also solve some notorious design problems.