DEV Community

Cover image for Single Element Loaders: Going 3D with CSS
Raj Aryan
Raj Aryan

Posted on

Single Element Loaders: Going 3D with CSS

CSS never ceases to surprise. With just one element, you can create spinners, dots, bars—and now, even 3D loaders. This is the fourth and final part of the Single Element Loaders series, and it takes things up a notch: simulating 3D cube loaders using nothing more than CSS gradients, pseudo-elements, and clever math.


The Split Cube Loader

The idea is simple: show three faces of a cube instead of all six. With a single HTML element and its ::before and ::after pseudos, you can create two halves that overlap to look like one cube.

Here’s the trick:

  • Conic gradients give each pseudo the illusion of depth with shaded sides.
  • clip-path defines the polygonal shape of each cube face.
  • Negative margins pull both halves together seamlessly.
  • Finally, a smooth keyframe animation makes the cube bounce.
.loader {
  --s: 150px; 
  --_d: calc(0.353 * var(--s)); 
  width: calc(var(--s) + var(--_d)); 
  aspect-ratio: 1;
  display: flex;
}

.loader::before,
.loader::after {
  content: "";
  flex: 1;
  background: conic-gradient(
    from -90deg at calc(100% - var(--_d)) var(--_d),
    #fff 135deg, #666 0 270deg, #aaa 0
  );
  clip-path: polygon(var(--_d) 0, 100% 0, 100% calc(100% - var(--_d)), 
    calc(100% - var(--_d)) 100%, 0 100%, 0 var(--_d));
  animation: load 1.5s infinite cubic-bezier(0, .5, .5, 1.8) alternate;
}

.loader::before { margin-right: calc(var(--_d) / -2); }
.loader::after { margin-left: calc(var(--_d) / -2); animation-delay: -.75s; }

@keyframes load {
  0%, 40% { transform: translateY(calc(var(--s) / -4)); }
  60%, 100% { transform: translateY(calc(var(--s) / 4)); }
}
Enter fullscreen mode Exit fullscreen mode

Result: a bouncing cube-like loader, animated in 3D—all from a single element.


The Progress Cube Loader

Next, we can adapt the same cube structure into a progress indicator.

Key tweaks:

  • Use opacity on the right half to simulate depth.
  • Add a blend color to the left side to create three shades from one color.
  • Animate the width of the left side, filling the cube gradually like a progress bar.
  • A bottom gradient completes the illusion of the cube’s base.
.loader {
  --s: 100px; 
  --_d: calc(0.353*var(--s)); 
  height: var(--s); 
  aspect-ratio: 3;
  display: flex;
  background: linear-gradient(#fff1 0 0) bottom / 100% var(--_d) no-repeat;
  clip-path: polygon(var(--_d) 0, 100% 0, 100% calc(100% - var(--_d)), 
    calc(100% - var(--_d)) 100%, 0 100%, 0 var(--_d));
}
.loader::before,
.loader::after {
  content: "";
  clip-path: inherit;
  background: conic-gradient(
    from -90deg at calc(100% - var(--_d)) var(--_d),
    #fff 135deg, #666 0 270deg, #aaa 0
  );
}
.loader::before {
  background-color: #CC333F; 
  background-blend-mode: multiply;
  margin-right: calc(var(--_d) / -2);
  animation: load 2.5s infinite linear;
}
.loader::after {
  flex: 1;
  margin-left: calc(var(--_d) / -2);
  opacity: 0.4;
}

@keyframes load {
  0%, 5% { width: var(--_d); }
  95%, 100% { width: 100%; }
}
Enter fullscreen mode Exit fullscreen mode

Now the cube fills like a bar, perfectly synced with its 3D illusion.


Going Beyond: Cube Patterns

If one cube isn’t enough, CSS lets you create entire grids of cubes with a single element. Using:

  • CSS variables to control size, rows, columns, and gaps.
  • A conic-gradient pattern for cube faces.
  • A mask layer to cut out cube shapes.

From there, animations like sliding cubes or blinking cube colors bring the illusion to life. Want a 10×10 cube grid? Just change --m and --n.


Variations Galore

With the same building blocks—pseudo-elements, gradients, clipping, blending, and variables—you can create loaders that:

  • Bounce in 3D
  • Fill like progress bars
  • Slide infinitely across the screen
  • Blink colors in sequence

The possibilities are endless, and all with a single element in your HTML.


Final Thoughts

From a simple spinner to complex 3D illusions, single-element loaders prove the power and flexibility of CSS. With just one <div>, you can build something visually rich, scalable, and reusable—no JavaScript required (unless you want to make it interactive).

This 3D finale wraps up the Single Element Loaders series, showing that sometimes the simplest markup can yield the most impressive results.

Top comments (0)