3D 변환 큐브

3D transform cube

면 6개를 translateZ 와 rotate 조합으로 세워 만든 진짜 3D 정육면체. perspective + transform-style: preserve-3d 조합의 정석 예제.

다른 이름: CSS cubepreserve-3d cube
···
html
<div class="wrap"><div class="stage"><div class="cube" id="cube">
  <i class="face f1">1</i><i class="face f2">2</i><i class="face f3">3</i><i class="face f4">4</i><i class="face f5">5</i><i class="face f6">6</i>
</div></div><div class="label">transform-style: preserve-3d</div></div>
css
.wrap{position:relative;display:grid;place-items:center;gap:14px}
.stage{perspective:700px}
.cube{position:relative;width:26vmin;max-width:110px;aspect-ratio:1;transform-style:preserve-3d;
  --h:calc(min(26vmin,110px) / 2);animation:spin 8s linear infinite}
.face{position:absolute;inset:0;display:grid;place-items:center;color:#fff;font:800 20px/1 sans-serif;
  opacity:.94;border:1px solid rgba(255,255,255,.2)}
.f1{background:#5b5bf7;transform:translateZ(var(--h))}
.f2{background:#f25c8a;transform:rotateY(180deg) translateZ(var(--h))}
.f3{background:#18c29c;transform:rotateY(90deg) translateZ(var(--h))}
.f4{background:#ffb648;transform:rotateY(-90deg) translateZ(var(--h))}
.f5{background:#a855f7;transform:rotateX(90deg) translateZ(var(--h))}
.f6{background:#22d3ee;transform:rotateX(-90deg) translateZ(var(--h))}
@keyframes spin{to{transform:rotateX(360deg) rotateY(360deg)}}
.label{color:#fff;font:600 12px monospace;opacity:.7}

면 하나는 그냥 정사각형 div 입니다. 이걸 정육면체 한 면으로 만들려면 "먼저 정면을 향하게 두고, 정육면체 반지름(한 변의 절반)만큼 z축으로 밀어낸다"를 6번 반복하면 됩니다 — translateZ(h) 는 그대로 앞면, rotateY(180deg) translateZ(h) 는 뒷면, rotateY(±90deg) translateZ(h) 는 좌우, rotateX(±90deg) translateZ(h) 는 위아래입니다.

핵심은 부모(정육면체 그룹)에 transform-style: preserve-3d 를 주는 것입니다 — 이게 없으면 자식들의 3D 배치가 하나의 평면으로 뭉개져 그냥 겹친 사각형처럼 보입니다. 여기에 조상 어딘가의 perspective 가 더해져야 비로소 원근감 있는 입체로 보입니다.

preserve-3d 는 overflow: hidden, opacity < 1, filter 가 걸린 조상을 지나가면 깨집니다(그 조상이 자신만의 평평한 렌더링 그룹을 만들기 때문). 큐브 구조를 만들었는데 갑자기 평평해 보인다면 그 사이 어딘가에 이 세 가지 중 하나가 있는지부터 의심하세요.

언제 쓰나

제품 쇼케이스, 로딩 인디케이터, 설정 스위처처럼 "회전하는 실물"을 표현할 때. 6면 전부 텍스트/이미지를 채우면 무거워지니 필요한 면만 내용을 채우세요.