3D✨ Premium

Isometric Grid

Nine indigo blocks in a 3 × 3 grid seen in isometric view (tilted 60°, turned −45°), each closed by a 20 px front face and left face; the block that is hovered, tapped or reached with the keyboard rises 30 px and turns pink-violet, like a drawer pulled out — one cell at a time, in pure CSS, no JavaScript.

CSS3DIsometric

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. 3D has 50 effects, including 8 free. Explore the category →

3 usage examples

The nine rehearsal rooms of a music studio — picking a slot — Isometric Grid example 1

① The nine rehearsal rooms of a music studio — picking a slot

WhenIsometric plan of the studio: nine numbered rooms; the hovered one rises and turns pink, and its card shows on the left ("Room 5 — 18 m², drums provided, €12 / h").
WhyA single cell lifting points to one room without doubt; raising several blocks at once, as the other Isometric Grid (fx-0026) does, would blur the choice.
SettingsGrid enlarged to 68 px cells (grid-template-columns: repeat(3, 68px), 10 px gap), 26 px faces, number painted on each cell; grid placed on the right, on the capture mouse's path; the room card follows the hovered cell.
The nine lockers of a smart locker bank — parcel pick-up app at a train station — Isometric Grid example 2

② The nine lockers of a smart locker bank — parcel pick-up app at a train station

WhenThe locker bank seen from above in isometric view, lockers A1 to C3: the assigned locker ("Locker C2") rises and takes color, the others stay gray; the pick-up code is shown next to it.
WhyThe cell coming out of the grid shows the exact spot of the locker; it is the same visual gesture as a drawer opening.
Settings46 px cells recolored slate gray (#64748b → #475569, faces #334155 and #3b4a5e), original pink-violet for the raised cell; the scene raises C2 in a loop with a class that reuses the hover values.
A nine-square garden bed — square-foot gardening app — Isometric Grid example 3

③ A nine-square garden bed — square-foot gardening app

WhenA 1.20 m bed in nine squares (Radish, Lettuce, Basil, Tomato…); the hovered square lifts, turns green and its sowing date shows on the right.
WhyThe isometric grid looks like the wooden bed seen from above; each square stays a separate compartment, and the raised one is the only card you read.
SettingsSoil-colored cells (#8b5e34 → #6f4a28, dark brown faces), green #86efac → #22c55e for the raised cell, vegetable name painted on each cell; the scene raises Radish, Basil and Tomato in turn.

How it works

The root .fx-0010-root (#0a0a0f background, at least 300 px tall) centers .isometric-container, which carries perspective: 1000px, then .isometric-grid: a CSS grid of 3 columns of 40 px, 8 px gap, turned by transform: rotateX(60deg) rotateZ(-45deg) and set to transform-style: preserve-3d so its children keep their own depth. The nine .isometric-cell elements (40 × 40 px, #6366f1 → #4f46e5 gradient, 4 px corners, tabindex="0") are preserve-3d too: their pseudo-elements become faces.

Each block has two faces, the ones you see at this angle. ::before is the front face: hung under the cell's bottom edge (top: 100%, 20 px tall, #3730a3), it pivots around that edge (transform-origin at the top, rotateX(-90deg)) and drops toward the ground. ::after is the left face: hung on the left edge (right: 100%, 20 px wide, #4338ca), it pivots around that edge (rotateY(-90deg)). The back and right faces would be hidden: they are not drawn. On hover (or :focus-visible), the cell takes translateZ(30px) and a #d946ef → #a855f7 gradient, its faces switch to #7c3aed and #8b5cf6, in 0.3 s. With 20 px faces, the raised block floats 10 px above the ground and reveals the dark hole of its slot: a drawer pulled out. Measured: 1.6% of pixels change when hovering the center cell, identically in Chromium 151 and Firefox 153 (0.2% apart).

Only the cells catch the pointer: pointer-events: none on the grid, auto on the cells. Measured in Chromium with touch emulation: without that rule, the touch goes to the tilted grid and no cell rises; with it, the touched cell rises. It is also why a pointer resting in a gap between two cells lifts nothing. A single :hover rule drives everything: there is only ever one raised cell, the one under the pointer or the one with focus.

Accessibility

  • Reduced motion: under prefers-reduced-motion: reduce, a block scoped to .fx-0010-root cancels the lift: the hovered or focused cell turns pink-violet in place. Measured in Chromium and Firefox: transform unchanged, 0.7% of pixels change on hover (1.6% without the preference).
  • Keyboard: the nine cells have tabindex="0"; Tab walks them in grid order, and focus gives the hover state plus a 2 px #f0abfc outline (11.2:1 on the background). The demo cells are empty div elements: when they stand for something (a room, a locker), name them with aria-label and, if they trigger an action, add role="button" and the Enter key in your script.
  • Contrast: the blocks' indigo measures 4.4:1 on the #0a0a0f background, the pink-violet 5.7:1; but between the two the gap is only 1.3:1. The lift (and the outline from the keyboard) marks the cell, not the color alone: under reduced motion, if the choice matters, add a text or a border.
  • Touch: with a finger, the tapped cell rises (measured with Chromium touch emulation and in Firefox) and stays raised until the next tap.

Browser compatibility

3D CSS on three levels (perspective on the container, preserve-3d on the grid then on each cell, faces as pseudo-elements), :focus-visible, no dependencies, no JavaScript. Measured in Chromium 151 and Firefox 153: same render at rest and on hover (0.2% apart), same reduced motion, 0 errors. Playwright's WebKit flattens all preserve-3d 3D, even a reference cube: its captures say nothing about Safari. Safari rendering not checked on a real Safari.

Chrome 86+✓ Full
Firefox 85+✓ Full
Safari✓ Not checked on a real Safari (nested 3D)
Edge 86+✓ Full
Mobile iOS✓ Not checked on a real iPhone
Android Chrome✓ Full (touch measured with Chromium emulation)

If the browser flattens the 3D, the faces fold into the grid's plane: you see flat cells, and the lift barely shows; the color change on hover remains. Without :focus-visible, keyboard focus only gets the browser's ring.

The code

HTML structure to paste into your page (the CSS + JS come with your purchase):

index.html — structure
<div class="fx-0010-root">
  <div class="demo-3d">
    <div class="isometric-container">   <!-- perspective: 1000px -->
      <div class="isometric-grid">   <!-- rotateX(60deg) rotateZ(-45deg), preserve-3d -->
        <div class="isometric-cell" tabindex="0"></div>   <!-- ::before front face, ::after left face -->
        … (9 cells)
      </div>
    </div>
  </div>
</div>

One-time payment, no subscription — the code is yours forever

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Cell size and count (CSS — grid-template-columns and .isometric-cell size) repeat(3, 40px); 40 × 40 px; 9 cells Change both together, and add as many div elements as cells: repeat(4, 40px) with sixteen cells gives a 4 × 4 board.
Gap (CSS — grid gap) 8 px Under 4 px, the blocks touch and the grid looks like a solid slab; above 12 px, they become separate islands.
Block height (CSS — height of ::before and width of ::after) 20 px Change both values together. At 30 px, equal to the lift, the raised block stays on the ground instead of floating.
Lift (CSS — hover translateZ) 30 px 50 px pulls the block out clearly; higher up, it covers part of the cell behind it.
Colors (CSS — cell gradient and both faces' background, at rest and on hover) #6366f1 → #4f46e5, faces #3730a3 / #4338ca; hover #d946ef → #a855f7, faces #7c3aed / #8b5cf6 Keep the front face darker than the left face, and both darker than the top: that is what gives light from above.
View angle (CSS — rotateX(60deg) rotateZ(-45deg)) 60° and −45° Between rotateX(55deg) and 65deg, the view stays close to isometric. Switching to rotateZ(45deg) shows the front and right faces instead: move ::after to the right edge (left: 100%, pivot on the left, rotateY(90deg)).

FAQ

Both carry the same name in the catalog, but they do different things. This one is a 3 × 3 grid in pure CSS: a single cell rises, the one you hover, tap or reach with the keyboard, and turns pink-violet — it is a picker. fx-0026 is a 4 × 4 slab driven by JavaScript: every block within 60 px of the pointer rises, more the closer it is, forming a bump that follows the mouse — it is a zone of influence. Pick this one to point to one cell, fx-0026 to show a radius or a relief.
With the grid turned −45° and tilted 60°, only the front face and the left face point toward you; the other two would be hidden behind the top of the block. Drawing them would not change the picture and would double the number of planes to paint. If you change the angle, move the faces (see the table above).
Yes: add a class (for instance .is-selected) that reuses the hover values — transform: translateZ(30px), the pink-violet gradient and both faces' colors — and set it on the chosen cell. The locker scene does exactly that for the assigned locker. Give that cell a readable name (aria-label, aria-current).