20 CSS Loaders 12 / 20

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.

Pure CSS MIT licensed
Live Demo Open in tab

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

Open in playground

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}
}

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.

Customize

  • 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.

Watch out for

  • 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.

Search CodeFronts

Loading…