Pure CSS Shapes & solids #loop #sass-loop

Rotating cube in pure CSS

Six faces placed with rotate + translateZ, spun by a single keyframe animation.

  • 35 lines of CSS
  • 6 lines of HTML
  • No JavaScript
  • No dependencies
  • MIT licensed

How it works

  1. Put perspective on the parent. It is the camera distance — smaller means more dramatic.
  2. Give the cube transform-style: preserve-3d, otherwise its children are flattened into its plane.
  3. Stack all six faces in the same spot, rotate each to face outward, then translateZ by half the side length.
  4. Animate only the cube. The faces ride along for free.

Key techniques

  • transform-style: preserve-3d
  • perspective
  • @keyframes
  • Sass @mixin + @for

Copy-paste code

HTML 6 lines

<div class="scene">
  <div class="cube">
    <div>1</div><div>2</div><div>3</div>
    <div>4</div><div>5</div><div>6</div>
  </div>
</div>

CSS 35 lines

.scene {
  perspective: 800px;
}

.cube {
  --s: 120px;
  position: relative;
  width: var(--s);
  height: var(--s);
  transform-style: preserve-3d;
  animation: spin 9s linear infinite;
}

.cube > * {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font: 700 1.5rem system-ui;
  background: rgb(139 108 255 / 0.28);
  border: 1px solid rgb(139 108 255 / 0.8);
}

/* turn each face outward, then push it half a side from the centre */
.cube > :nth-child(1) { transform: rotateY(0deg)   translateZ(calc(var(--s) / 2)); }
.cube > :nth-child(2) { transform: rotateY(90deg)  translateZ(calc(var(--s) / 2)); }
.cube > :nth-child(3) { transform: rotateY(180deg) translateZ(calc(var(--s) / 2)); }
.cube > :nth-child(4) { transform: rotateY(-90deg) translateZ(calc(var(--s) / 2)); }
.cube > :nth-child(5) { transform: rotateX(90deg)  translateZ(calc(var(--s) / 2)); }
.cube > :nth-child(6) { transform: rotateX(-90deg) translateZ(calc(var(--s) / 2)); }

@keyframes spin {
  from { transform: rotateX(-24deg) rotateY(0deg); }
  to   { transform: rotateX(-24deg) rotateY(360deg); }
}

Sass source 32 lines

@use '../mixins' as *;

.d-cube {
  --s: 96px;
  position: relative;
  width: var(--s);
  height: var(--s);
  transform-style: preserve-3d;
  animation: d-cube-spin 9s linear infinite;
  @include cube-faces(var(--s));

  i {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-size: 28px;
    font-style: normal;
    font-weight: 800;
    @include face;
  }
}

@keyframes d-cube-spin {
  from {
    transform: rotateX(-24deg) rotateY(0deg);
  }

  to {
    transform: rotateX(-24deg) rotateY(360deg);
  }
}
Standalone snippet · plain CSS, no build step, no dependencies.