Isometric 3D
Flat 3D perspective using isometric projection — geometric depth without real 3D rendering.
MCP
Code
:root {
--iso-bg: #f0f4ff;
--iso-indigo: #5c6bc0;
--iso-indigo-dark: #3949ab;
--iso-indigo-light: #7986cb;
--iso-blue: #42a5f5;
--iso-cyan: #26c6da;
--iso-text: #1a1f3a;
--iso-text-muted: #5c6480;
--iso-border: #d0d7f0;
--iso-card-radius: 4px;
--font: "Space Grotesk", system-ui, sans-serif;
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: var(--font);
background-color: var(--iso-bg);
color: var(--iso-text);
min-height: 100vh;
overflow-x: hidden;
position: relative;
}
/* ── Background dot grid ── */
.bg-grid {
position: fixed;
inset: 0;
z-index: 0;
background-image: radial-gradient(circle, #a0aac8 1px, transparent 1px);
background-size: 28px 28px;
opacity: 0.45;
pointer-events: none;
}
/* ── Decorative floating cubes ── */
.deco-cubes {
position: fixed;
inset: 0;
z-index: 0;
pointer-events: none;
overflow: hidden;
}
.deco-cube {
position: absolute;
width: 40px;
height: 40px;
transform-style: preserve-3d;
transform: rotateX(45deg) rotateZ(-45deg);
}
.deco-cube--a {
top: 8%;
left: 6%;
opacity: 0.35;
transform: rotateX(45deg) rotateZ(-45deg) scale(2.5);
}
.deco-cube--b {
top: 65%;
right: 5%;
opacity: 0.25;
transform: rotateX(45deg) rotateZ(-45deg) scale(3.5);
}
.deco-cube--c {
top: 30%;
right: 12%;
opacity: 0.2;
transform: rotateX(45deg) rotateZ(-45deg) scale(1.8);
}
.face {
position: absolute;
width: 40px;
height: 40px;
}
.face--top {
background: var(--iso-indigo);
transform: rotateX(90deg) translateZ(20px);
}
.face--left {
background: var(--iso-indigo-dark);
transform: rotateY(-90deg) translateZ(0) translateX(-20px);
width: 40px;
height: 40px;
top: 0;
}
.face--right {
background: var(--iso-indigo-light);
transform: translateZ(20px);
}
/* ── Page layout ── */
.page {
position: relative;
z-index: 1;
max-width: 860px;
margin: 0 auto;
padding: 56px 24px 80px;
}
/* ── Header ── */
.header {
text-align: center;
margin-bottom: 64px;
}
.header__badge {
display: inline-block;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.12em;
color: var(--iso-indigo);
background: rgba(92, 107, 192, 0.1);
border: 1px solid rgba(92, 107, 192, 0.25);
padding: 4px 12px;
margin-bottom: 20px;
border-radius: var(--iso-card-radius);
text-transform: uppercase;
}
.header__title {
font-size: clamp(48px, 8vw, 88px);
font-weight: 700;
line-height: 1;
color: var(--iso-text);
letter-spacing: -0.03em;
}
.header__title span {
color: var(--iso-indigo);
display: block;
}
.header__tagline {
margin-top: 20px;
font-size: 18px;
color: var(--iso-text-muted);
font-weight: 400;
max-width: 400px;
margin-inline: auto;
}
/* ── Showcase grid ── */
.showcase {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 48px;
align-items: start;
}
@media (max-width: 640px) {
.showcase {
grid-template-columns: 1fr;
}
}
/* ── Isometric card ── */
.card-section {
display: flex;
justify-content: center;
padding: 40px 0;
}
.iso-card-wrap {
position: relative;
display: inline-block;
}
.iso-card {
position: relative;
z-index: 2;
background: var(--iso-indigo);
border-radius: var(--iso-card-radius);
padding: 28px;
width: 280px;
color: white;
/* Isometric stacked shadow gives the 3-face cube illusion */
box-shadow: -6px 6px 0 var(--iso-indigo-dark), -12px 12px 0 #2e3a8a, -18px 18px 0
rgba(41, 53, 120, 0.4), 0 24px 48px rgba(57, 73, 171, 0.35);
cursor: pointer;
transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.35s ease;
will-change: transform;
}
.iso-card:hover {
transform: translate(4px, -4px);
box-shadow: -10px 10px 0 var(--iso-indigo-dark), -20px 20px 0 #2e3a8a, -26px 26px 0
rgba(41, 53, 120, 0.3), 0 32px 60px rgba(57, 73, 171, 0.45);
}
.iso-shadow-left {
position: absolute;
left: -18px;
bottom: -18px;
width: 100%;
height: 100%;
background: rgba(46, 58, 138, 0.15);
border-radius: var(--iso-card-radius);
z-index: 1;
transform: skewY(-3deg);
}
.iso-shadow-bottom {
position: absolute;
left: 4px;
bottom: -28px;
width: 90%;
height: 20px;
background: rgba(57, 73, 171, 0.2);
border-radius: 50%;
filter: blur(8px);
z-index: 0;
}
/* ── Card content ── */
.iso-card__top {
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 24px;
}
.avatar {
flex-shrink: 0;
border-radius: var(--iso-card-radius);
overflow: hidden;
border: 2px solid rgba(255, 255, 255, 0.2);
}
.profile-name {
font-size: 18px;
font-weight: 700;
color: #fff;
}
.profile-role {
font-size: 13px;
color: rgba(255, 255, 255, 0.7);
margin-top: 2px;
font-weight: 500;
}
.iso-card__stats {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
border-top: 1px solid rgba(255, 255, 255, 0.15);
padding-top: 20px;
}
.stat {
text-align: center;
}
.stat__value {
display: block;
font-size: 22px;
font-weight: 700;
color: #fff;
letter-spacing: -0.02em;
}
.stat__label {
display: block;
font-size: 11px;
color: rgba(255, 255, 255, 0.6);
text-transform: uppercase;
letter-spacing: 0.08em;
margin-top: 2px;
}
/* ── Controls section ── */
.controls-section {
display: flex;
flex-direction: column;
gap: 32px;
padding-top: 40px;
}
/* ── Buttons ── */
.button-group {
display: flex;
flex-direction: column;
gap: 12px;
}
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 12px 24px;
font-family: var(--font);
font-size: 14px;
font-weight: 600;
letter-spacing: 0.02em;
border-radius: var(--iso-card-radius);
border: none;
cursor: pointer;
transition: transform 0.15s ease, box-shadow 0.15s ease;
text-transform: uppercase;
letter-spacing: 0.06em;
}
.btn--primary {
background: var(--iso-indigo);
color: white;
box-shadow: -3px 3px 0 var(--iso-indigo-dark), -6px 6px 0 rgba(57, 73, 171, 0.4);
}
.btn--primary:hover {
transform: translate(2px, -2px);
box-shadow: -5px 5px 0 var(--iso-indigo-dark), -10px 10px 0 rgba(57, 73, 171, 0.35);
}
.btn--primary:active {
transform: translate(-1px, 1px);
box-shadow: -1px 1px 0 var(--iso-indigo-dark);
}
.btn--secondary {
background: rgba(92, 107, 192, 0.12);
color: var(--iso-indigo);
border: 1px solid rgba(92, 107, 192, 0.3);
box-shadow: -3px 3px 0 rgba(92, 107, 192, 0.2);
}
.btn--secondary:hover {
transform: translate(2px, -2px);
background: rgba(92, 107, 192, 0.2);
box-shadow: -5px 5px 0 rgba(92, 107, 192, 0.3);
}
.btn--ghost {
background: transparent;
color: var(--iso-indigo);
border: 2px solid var(--iso-indigo);
}
.btn--ghost:hover {
background: var(--iso-indigo);
color: white;
box-shadow: -3px 3px 0 var(--iso-indigo-dark);
}
/* ── Input ── */
.input-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.input-label {
font-size: 12px;
font-weight: 700;
color: var(--iso-text-muted);
text-transform: uppercase;
letter-spacing: 0.1em;
}
.input {
font-family: var(--font);
font-size: 14px;
padding: 11px 14px;
border: 2px solid var(--iso-border);
border-radius: var(--iso-card-radius);
background: white;
color: var(--iso-text);
outline: none;
transition: border-color 0.2s ease, box-shadow 0.2s ease;
box-shadow: -3px 3px 0 var(--iso-border);
}
.input:focus {
border-color: var(--iso-indigo);
box-shadow: -4px 4px 0 rgba(92, 107, 192, 0.3);
}
.input::placeholder {
color: #a0a8c0;
}
/* ── Badges ── */
.badge-row {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.badge {
display: inline-block;
font-size: 11px;
font-weight: 700;
padding: 4px 10px;
border-radius: var(--iso-card-radius);
text-transform: uppercase;
letter-spacing: 0.08em;
}
.badge--indigo {
background: rgba(92, 107, 192, 0.15);
color: var(--iso-indigo);
border: 1px solid rgba(92, 107, 192, 0.3);
}
.badge--blue {
background: rgba(66, 165, 245, 0.12);
color: #1976d2;
border: 1px solid rgba(66, 165, 245, 0.3);
}
.badge--cyan {
background: rgba(38, 198, 218, 0.12);
color: #00838f;
border: 1px solid rgba(38, 198, 218, 0.3);
}
.badge--dark {
background: rgba(26, 31, 58, 0.08);
color: var(--iso-text);
border: 1px solid rgba(26, 31, 58, 0.15);
}/* Isometric 3D — Interactive JS */
(function () {
"use strict";
const card = document.getElementById("isoCard");
if (!card) return;
// ── Card tilt on mouse move (subtle Y-axis rotation within iso context) ──
let animFrame = null;
let currentTiltX = 0;
let currentTiltY = 0;
let targetTiltX = 0;
let targetTiltY = 0;
let isHovering = false;
card.addEventListener("mouseenter", () => {
isHovering = true;
startTiltAnimation();
});
card.addEventListener("mouseleave", () => {
isHovering = false;
targetTiltX = 0;
targetTiltY = 0;
});
card.addEventListener("mousemove", (e) => {
const rect = card.getBoundingClientRect();
const cx = rect.left + rect.width / 2;
const cy = rect.top + rect.height / 2;
const dx = (e.clientX - cx) / (rect.width / 2);
const dy = (e.clientY - cy) / (rect.height / 2);
// Limit to ±8deg tilt
targetTiltX = -dy * 8;
targetTiltY = dx * 8;
});
function startTiltAnimation() {
if (animFrame) return;
function tick() {
// Lerp toward target
currentTiltX += (targetTiltX - currentTiltX) * 0.12;
currentTiltY += (targetTiltY - currentTiltY) * 0.12;
// Apply: isometric base transform + tilt
card.style.transform = `
rotateX(${currentTiltX}deg)
rotateY(${currentTiltY}deg)
`;
// Stop when close enough and not hovering
const settled =
Math.abs(targetTiltX - currentTiltX) < 0.01 && Math.abs(targetTiltY - currentTiltY) < 0.01;
if (settled && !isHovering) {
card.style.transform = "";
animFrame = null;
return;
}
animFrame = requestAnimationFrame(tick);
}
animFrame = requestAnimationFrame(tick);
}
// ── Stagger entrance animation for stats ──
const stats = document.querySelectorAll(".stat");
stats.forEach((stat, i) => {
stat.style.opacity = "0";
stat.style.transform = "translateY(12px)";
stat.style.transition = `opacity 0.4s ease ${0.3 + i * 0.1}s, transform 0.4s ease ${0.3 + i * 0.1}s`;
});
// Trigger after a short delay
requestAnimationFrame(() => {
requestAnimationFrame(() => {
stats.forEach((stat) => {
stat.style.opacity = "1";
stat.style.transform = "translateY(0)";
});
});
});
// ── Badge entrance: slide in from right ──
const badges = document.querySelectorAll(".badge");
badges.forEach((badge, i) => {
badge.style.opacity = "0";
badge.style.transform = "translateX(16px)";
badge.style.transition = `opacity 0.35s ease ${0.5 + i * 0.08}s, transform 0.35s ease ${0.5 + i * 0.08}s`;
});
requestAnimationFrame(() => {
requestAnimationFrame(() => {
badges.forEach((badge) => {
badge.style.opacity = "1";
badge.style.transform = "translateX(0)";
});
});
});
// ── Button: isometric press effect ──
document.querySelectorAll(".btn").forEach((btn) => {
btn.addEventListener("mousedown", () => {
btn.style.transition = "transform 0.08s ease, box-shadow 0.08s ease";
});
btn.addEventListener("mouseup", () => {
btn.style.transition = "";
});
});
// ── Decorative cube parallax ──
const decoCubes = document.querySelectorAll(".deco-cube");
document.addEventListener("mousemove", (e) => {
const px = (e.clientX / window.innerWidth - 0.5) * 2;
const py = (e.clientY / window.innerHeight - 0.5) * 2;
decoCubes.forEach((cube, i) => {
const depth = (i + 1) * 6;
const ox = px * depth;
const oy = py * depth;
const baseTransform = cube.style.transform || "";
// Keep existing scale/rotate, just offset translate
cube.style.translate = `${ox}px ${oy}px`;
});
});
})();<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
<title>Isometric 3D — Design Style</title>
</head>
<body>
<!-- Background grid decoration -->
<div class="bg-grid" aria-hidden="true"></div>
<!-- Floating iso cubes decoration -->
<div class="deco-cubes" aria-hidden="true">
<div class="deco-cube deco-cube--a">
<div class="face face--top"></div>
<div class="face face--left"></div>
<div class="face face--right"></div>
</div>
<div class="deco-cube deco-cube--b">
<div class="face face--top"></div>
<div class="face face--left"></div>
<div class="face face--right"></div>
</div>
<div class="deco-cube deco-cube--c">
<div class="face face--top"></div>
<div class="face face--left"></div>
<div class="face face--right"></div>
</div>
</div>
<div class="page">
<!-- Header -->
<header class="header">
<div class="header__badge">DESIGN SYSTEM</div>
<h1 class="header__title">Isometric<br /><span>3D</span></h1>
<p class="header__tagline">Geometric depth without real 3D rendering — precision by design.</p>
</header>
<!-- Main showcase grid -->
<main class="showcase">
<!-- Isometric profile card -->
<section class="card-section">
<div class="iso-card-wrap">
<div class="iso-card" id="isoCard">
<!-- Top face content -->
<div class="iso-card__top">
<div class="avatar">
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="48" height="48" rx="4" fill="#7986CB"/>
<circle cx="24" cy="18" r="8" fill="#C5CAE9"/>
<path d="M8 40c0-8.837 7.163-16 16-16s16 7.163 16 16" fill="#C5CAE9"/>
</svg>
</div>
<div class="profile-info">
<h2 class="profile-name">Alex Mercer</h2>
<p class="profile-role">Senior Architect</p>
</div>
</div>
<!-- Stats row -->
<div class="iso-card__stats">
<div class="stat">
<span class="stat__value">248</span>
<span class="stat__label">Projects</span>
</div>
<div class="stat">
<span class="stat__value">4.9</span>
<span class="stat__label">Rating</span>
</div>
<div class="stat">
<span class="stat__value">12k</span>
<span class="stat__label">Followers</span>
</div>
</div>
</div>
<!-- Simulated side faces via pseudo shadow cubes -->
<div class="iso-shadow-left" aria-hidden="true"></div>
<div class="iso-shadow-bottom" aria-hidden="true"></div>
</div>
</section>
<!-- Controls section -->
<section class="controls-section">
<!-- Buttons -->
<div class="button-group">
<button class="btn btn--primary">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 1l2 5h5l-4 3 1.5 5L8 11l-4.5 3L5 9 1 6h5L8 1z" fill="currentColor"/></svg>
Primary Action
</button>
<button class="btn btn--secondary">Secondary</button>
<button class="btn btn--ghost">Ghost / Outline</button>
</div>
<!-- Input -->
<div class="input-group">
<label class="input-label" for="isoInput">Project Name</label>
<input class="input" id="isoInput" type="text" placeholder="Enter project identifier..." />
</div>
<!-- Badges -->
<div class="badge-row">
<span class="badge badge--indigo">Isometric</span>
<span class="badge badge--blue">Geometric</span>
<span class="badge badge--cyan">3D CSS</span>
<span class="badge badge--dark">Depth</span>
</div>
</section>
</main>
</div>
<script src="script.js"></script>
</body>
</html>Isometric 3D
Isometric design creates the illusion of three-dimensional depth using pure CSS transforms and careful color shading — no WebGL, no Three.js, no real 3D engine required. The aesthetic draws from engineering blueprints, retro game art, and technical illustration, giving interfaces a precise, architectural quality that feels both futuristic and grounded.
The signature technique is the three-face box: a top face, a left face, and a right face, each rendered at a slightly different shade to simulate directional lighting from the upper-left. CSS transform: rotateX(60deg) rotateZ(-45deg) combined with transform-style: preserve-3d creates the isometric viewing angle. Alternatively, stacked box-shadow offsets produce a flat-card version that reads as isometric without the transform complexity.
This style works best on light backgrounds where the depth shadows read clearly. Decorative isometric grids — subtle dot matrices or parallelogram patterns — reinforce the spatial metaphor without cluttering the UI.
Key characteristics
- Three-face cube illusion using CSS transforms or layered box-shadows
- Strict indigo/blue/cyan palette (
#5C6BC0,#42A5F5,#26C6DA) for cohesion - Right-angle or 4px-radius UI elements — no organic shapes
- Geometric dot-grid background decoration
- Hover interactions that rotate or lift cards along the isometric axis
When to use it
Deploy the Isometric 3D style for developer tools, data visualization dashboards, architecture or infrastructure product landing pages, and any context where precision and technical sophistication are brand values. Avoid it for content-heavy reading experiences where the visual weight of 3D elements would distract from text.