20 CSS Loaders12 / 20

Pure CSSMIT licensed

CSS Cube Flip 3D Loader

Three three-dimensional CSS loaders — a six-face spinning cube, a folding grid of four squares, and a nested wireframe box — using CSS 3D transforms and preserve-3d for depth.

Published

Live Demo
Try it

This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.

The code

<div class="ld-12">
  <div class="ld-12__stage">
    <div class="ld-12__cell">
      <div style="perspective:200px">
        <div class="ld-12__cube" style="position:relative">
          <div class="ld-12__face ld-12__face--front"></div>
          <div class="ld-12__face ld-12__face--back"></div>
          <div class="ld-12__face ld-12__face--left"></div>
          <div class="ld-12__face ld-12__face--right"></div>
          <div class="ld-12__face ld-12__face--top"></div>
          <div class="ld-12__face ld-12__face--bottom"></div>
        </div>
.ld-12,
.ld-12 *,
.ld-12 *::before,
.ld-12 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.ld-12 {
  --bg: #12151e;
  --c1: #ff9f43;
  --c2: #ee5a24;
  --c3: #a29bfe;
  --c4: #6c5ce7;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  font-family: 'Segoe UI',sans-serif;
  perspective: 600px;
}

.ld-12__stage {
  display: flex;
  gap: 80px;
  flex-wrap: wrap;
  justify-content: center;
  padding: 40px;
  align-items: center;
}

.ld-12__cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
}

.ld-12__label {
  color: rgba(255,255,255,.4);
  font-size: 11px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
}
/* Flip cube */

.ld-12__cube {
  width: 50px;
  height: 50px;
  transform-style: preserve-3d;
  animation: ld-12-cube-flip 2s ease-in-out infinite;
}

.ld-12__face {
  position: absolute;
  width: 50px;
  height: 50px;
  border: 2px solid var(--c1);
  display: flex;
  align-items: center;
  justify-content: center;
}

.ld-12__face--front {
  transform: translateZ(25px);
  background: rgba(255,159,67,.15);
}

.ld-12__face--back {
  transform: rotateY(180deg) translateZ(25px);
  background: rgba(255,159,67,.1);
}

.ld-12__face--left {
  transform: rotateY(-90deg) translateZ(25px);
  background: rgba(238,90,36,.1);
}

.ld-12__face--right {
  transform: rotateY(90deg) translateZ(25px);
  background: rgba(238,90,36,.15);
}

.ld-12__face--top {
  transform: rotateX(90deg) translateZ(25px);
  background: rgba(255,159,67,.05);
}

.ld-12__face--bottom {
  transform: rotateX(-90deg) translateZ(25px);
  background: rgba(238,90,36,.05);
}

@keyframes ld-12-cube-flip {
  0% {
    transform: rotateX(0) rotateY(0);
  }

  33% {
    transform: rotateX(90deg) rotateY(0);
  }

  66% {
    transform: rotateX(90deg) rotateY(90deg);
  }

  100% {
    transform: rotateX(180deg) rotateY(90deg);
  }
}
/* Folding squares */

.ld-12__fold {
  width: 40px;
  height: 40px;
  position: relative;
}

.ld-12__fold span {
  position: absolute;
  width: 18px;
  height: 18px;
  background: var(--c3);
  animation: ld-12-fold 2.4s ease-in-out infinite;
}

.ld-12__fold span:nth-child(1) {
  top: 0;
  left: 0;
  transform-origin: bottom right;
  animation-delay: 0s;
}

.ld-12__fold span:nth-child(2) {
  top: 0;
  right: 0;
  transform-origin: bottom left;
  animation-delay: .3s;
  background: rgba(162,155,254,.7);
}

.ld-12__fold span:nth-child(3) {
  bottom: 0;
  right: 0;
  transform-origin: top left;
  animation-delay: .6s;
  background: rgba(162,155,254,.5);
}

.ld-12__fold span:nth-child(4) {
  bottom: 0;
  left: 0;
  transform-origin: top right;
  animation-delay: .9s;
  background: rgba(162,155,254,.3);
}

@keyframes ld-12-fold {
  0%,
    10%,
    100% {
    transform: perspective(140px) rotateX(0) rotateY(0);
  }

  50% {
    transform: perspective(140px) rotateX(-180deg) rotateY(0);
  }
}
/* Rotating box */

.ld-12__box {
  width: 50px;
  height: 50px;
  border: 3px solid var(--c4);
  position: relative;
  animation: ld-12-box-spin 3s linear infinite;
  transform-style: preserve-3d;
}

.ld-12__box::before,
.ld-12__box::after {
  content: '';
  position: absolute;
  border: 3px solid rgba(108,92,231,.4);
}

.ld-12__box::before {
  inset: -12px;
  transform: rotateY(45deg);
  border-color: rgba(108,92,231,.3);
}

.ld-12__box::after {
  inset: -6px;
  transform: rotateX(45deg);
  border-color: rgba(108,92,231,.2);
}

@keyframes ld-12-box-spin {
  to {
    transform: rotateX(360deg) rotateY(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .ld-12__cube,
    .ld-12__fold span,
    .ld-12__box {
    animation: none;
  }
}
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Loader from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Cube Flip 3D Loader
Source: https://codefronts.com/motion/css-loader-designs/css-cube-flip-3d-loader/

Three three-dimensional CSS loaders — a six-face spinning cube, a folding grid of four squares, and a nested wireframe box — using CSS 3D transforms and preserve-3d for depth.
## HTML
```html
<div class="ld-12">
  <div class="ld-12__stage">
    <div class="ld-12__cell">
      <div style="perspective:200px">
        <div class="ld-12__cube" style="position:relative">
          <div class="ld-12__face ld-12__face--front"></div>
          <div class="ld-12__face ld-12__face--back"></div>
          <div class="ld-12__face ld-12__face--left"></div>
          <div class="ld-12__face ld-12__face--right"></div>
          <div class="ld-12__face ld-12__face--top"></div>
          <div class="ld-12__face ld-12__face--bottom"></div>
        </div>
```
## CSS
```css
.ld-12,
.ld-12 *,
.ld-12 *::before,
.ld-12 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.ld-12 {
  --bg: #12151e;
  --c1: #ff9f43;
  --c2: #ee5a24;
  --c3: #a29bfe;
  --c4: #6c5ce7;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  font-family: 'Segoe UI',sans-serif;
  perspective: 600px;
}

.ld-12__stage {
  display: flex;
  gap: 80px;
  flex-wrap: wrap;
  justify-content: center;
  padding: 40px;
  align-items: center;
}

.ld-12__cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
}

.ld-12__label {
  color: rgba(255,255,255,.4);
  font-size: 11px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
}
/* Flip cube */

.ld-12__cube {
  width: 50px;
  height: 50px;
  transform-style: preserve-3d;
  animation: ld-12-cube-flip 2s ease-in-out infinite;
}

.ld-12__face {
  position: absolute;
  width: 50px;
  height: 50px;
  border: 2px solid var(--c1);
  display: flex;
  align-items: center;
  justify-content: center;
}

.ld-12__face--front {
  transform: translateZ(25px);
  background: rgba(255,159,67,.15);
}

.ld-12__face--back {
  transform: rotateY(180deg) translateZ(25px);
  background: rgba(255,159,67,.1);
}

.ld-12__face--left {
  transform: rotateY(-90deg) translateZ(25px);
  background: rgba(238,90,36,.1);
}

.ld-12__face--right {
  transform: rotateY(90deg) translateZ(25px);
  background: rgba(238,90,36,.15);
}

.ld-12__face--top {
  transform: rotateX(90deg) translateZ(25px);
  background: rgba(255,159,67,.05);
}

.ld-12__face--bottom {
  transform: rotateX(-90deg) translateZ(25px);
  background: rgba(238,90,36,.05);
}

@keyframes ld-12-cube-flip {
  0% {
    transform: rotateX(0) rotateY(0);
  }

  33% {
    transform: rotateX(90deg) rotateY(0);
  }

  66% {
    transform: rotateX(90deg) rotateY(90deg);
  }

  100% {
    transform: rotateX(180deg) rotateY(90deg);
  }
}
/* Folding squares */

.ld-12__fold {
  width: 40px;
  height: 40px;
  position: relative;
}

.ld-12__fold span {
  position: absolute;
  width: 18px;
  height: 18px;
  background: var(--c3);
  animation: ld-12-fold 2.4s ease-in-out infinite;
}

.ld-12__fold span:nth-child(1) {
  top: 0;
  left: 0;
  transform-origin: bottom right;
  animation-delay: 0s;
}

.ld-12__fold span:nth-child(2) {
  top: 0;
  right: 0;
  transform-origin: bottom left;
  animation-delay: .3s;
  background: rgba(162,155,254,.7);
}

.ld-12__fold span:nth-child(3) {
  bottom: 0;
  right: 0;
  transform-origin: top left;
  animation-delay: .6s;
  background: rgba(162,155,254,.5);
}

.ld-12__fold span:nth-child(4) {
  bottom: 0;
  left: 0;
  transform-origin: top right;
  animation-delay: .9s;
  background: rgba(162,155,254,.3);
}

@keyframes ld-12-fold {
  0%,
    10%,
    100% {
    transform: perspective(140px) rotateX(0) rotateY(0);
  }

  50% {
    transform: perspective(140px) rotateX(-180deg) rotateY(0);
  }
}
/* Rotating box */

.ld-12__box {
  width: 50px;
  height: 50px;
  border: 3px solid var(--c4);
  position: relative;
  animation: ld-12-box-spin 3s linear infinite;
  transform-style: preserve-3d;
}

.ld-12__box::before,
.ld-12__box::after {
  content: '';
  position: absolute;
  border: 3px solid rgba(108,92,231,.4);
}

.ld-12__box::before {
  inset: -12px;
  transform: rotateY(45deg);
  border-color: rgba(108,92,231,.3);
}

.ld-12__box::after {
  inset: -6px;
  transform: rotateX(45deg);
  border-color: rgba(108,92,231,.2);
}

@keyframes ld-12-box-spin {
  to {
    transform: rotateX(360deg) rotateY(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .ld-12__cube,
    .ld-12__fold span,
    .ld-12__box {
    animation: none;
  }
}
```

How this works

The 3D cube uses a wrapper with transform-style: preserve-3d and six child divs each positioned as a face using translateZ and rotateX/Y(90deg) transforms. The keyframe rotates the assembly through three compound transforms — rotateX(90deg), then rotateY(90deg), then rotateX(180deg) — creating a continuous tumble that never returns to a boring flat orientation. Semi-transparent face backgrounds allow glimpses through to opposite faces.

The folding grid places four squares in the corners of a 40×40px container, each with a different transform-origin pointing inward. They run identical perspective(140px) rotateX(-180deg) keyframes staggered by 0.3s, so each square folds down sequentially like pages being turned. The wireframe box uses nested ::before and ::after pseudo-elements with rotateX(45deg) and rotateY(45deg) to create a cuboid skeleton that spins on two axes simultaneously.

Make it yours

  • Adjust the cube face colour by editing background: rgba(255,159,67,.15) — increase opacity for more opaque faces or switch to solid colours for a toy-block look.
  • Speed up the cube tumble by reducing animation-duration from 2s to 1s — the compound rotation keyframe still produces a natural motion at higher speeds.
  • Change the folding grid colours by assigning different background colours per nth-child span for a Rubik's-cube-style effect.
  • Increase wireframe box thickness by adding a box-shadow: inset 0 0 0 1px on the box and pseudo-elements for more visible edges.
  • Use perspective on the parent container rather than the element itself for more predictable depth calculations when multiple 3D loaders appear together.

Gotchas — read before shipping

  • transform-style: preserve-3d must be on the wrapper, not the faces — applying it to a face with no 3D children has no effect and is a common setup error.
  • The folding grid requires perspective inside each face's own transform value (perspective(140px) rotateX()) rather than on the parent — the parent-level perspective would sum with the face's local transform incorrectly.
  • iOS Safari clips preserve-3d subtrees when the parent has overflow: hidden — never combine 3D loaders with overflow clipping on the same element.

Browser support

ChromeSafariFirefoxEdge
49+9+44+49+

CSS 3D transforms and preserve-3d are universally supported; iOS Safari requires no overflow:hidden on 3D parents.

Techniques used in this demo

3D transforms (perspective + preserve-3d)@keyframesMDN ↗

Search CodeFronts

Loading…