Motion adds a lot to isometric scenes, and it is also the fastest way to make someone feel unwell. Wrap every animation in a prefers-reduced-motion query. For readers who ask for less motion we keep the scene still and use a small colour change on hover instead, which keeps the interface responsive without any movement.
A code editor, a modern browser and about twenty minutes. No libraries or build step.
Scaling for small screens
Typography on a tilted plane is readable only in small doses. A single word on the side of a block looks great; a paragraph set at an angle is exhausting. Keep running text flat and upright, and save the skewed type for labels, numbers and the occasional headline where the shape of the word matters more than speed.
Set the unit
Define
--unit: 2remon the scene so every size derives from one value.Build the columns
Read each value from a
data-valueattribute and set the block height withcalc().Label the bars
Keep labels flat and upright below the chart so they stay readable.
Describe the chart
Add a visually hidden table with the same numbers for screen readers.
The code
Tile engines figured out draw order decades ago. Sort by the sum of the column and row, draw from the smallest sum to the largest, and most scenes just work. Tall objects that span several tiles need special care, but the simple rule covers floors, walls and small props, which is most of what a blog illustration needs.
Browser support for 3D transforms is excellent today, with a few sharp edges. The main one is that certain properties, such as overflow hidden or some filters, quietly flatten a preserve-3d context. If a face disappears or a block turns flat, look for one of those on an ancestor before you start rewriting your transforms.
The best way to learn isometric CSS is to rebuild something you see every day. A mug, a keyboard key or a stack of books all make good first projects. They are simple enough to finish in an evening, and each one teaches a different trick, from rounded tops to repeating elements.
.floor { background-image: repeating-linear-gradient(30deg, var(--line) 0 1px, transparent 1px 40px), repeating-linear-gradient(150deg, var(--line) 0 1px, transparent 1px 40px);}
Colours used
Keeping everything on the grid
Grids are the backbone of every scene we draw. A single grid unit decides tile width, block height and spacing, which is why our illustrations line up even when three different people made them. When something looks off, the first thing we check is whether one element quietly ignored the grid.
Shadows on the floor sell the idea that a block has weight. A blurred ellipse, skewed to match the grid and placed slightly offset from the light, is usually enough. Real shadows would change with the height of the block, and adding that detail makes towers and stairs look much more convincing.
Edge lines deserve more attention than they usually get. A thin, slightly darker line along the bottom edges grounds each block, and a lighter line on the top edge suggests a highlight. Using currentColor for those lines means a single colour change on the wrapper restyles every outline in the scene.
What you built
- A cube with three shaded faces
- A floor grid from gradients
- A hover state that lifts the block
Mateo Rossi
How would you handle text that needs to wrap on one of the faces?
Tess Walsh
Tiny typo in the second code block: the unit is missing on the translate value.