// You can play with it using the different settings in the CSS section.
View Compiled
$show-face: false;
$hide-backface: false;
$random-color: true; // priority
$random-border: false;
$random-face: false;

$length: 3;
$size: 75vmin;
$time: 30s;
$ratio-border: 0.025;
$color-background: #170a19;
$opacity-border: 1;
$opacity-face: 0.05;

$colors: (
	#f46060,
	#ff8364,
	#ffb677,
	#acdeaa,
	#8ed6ff,
	#6886c5,
	#cca8e9,
	#726a95,
	#709fb0,
	#f4ebc1,
	#e36387,
	#d8345f,
	#f7e8f0
);

@function random-color($colors: $colors, $length: length($colors)) {
	@return nth($colors, random($length));
}

$color-border: random-color();
$color-face: random-color();

@mixin cube-world($length: $length, $size: $size, $gap: null, $selector: li) {
	$indice: floor($length / 2);
	$diameter: $size / $length;
	$radius: $diameter / 2;
	$gap: if($gap, $gap, $diameter * 2);
	$space: $diameter + $gap;
	$distance: $space * $indice;
	$grid: $length * $length;

	:root {
		--length: #{$grid * $length};
		--distance-front: #{$distance * 2 - $gap / 2};
		--distance-back: #{-2 * $distance + $gap / 2};
		--perspective: #{$distance + $diameter};
		--diameter: #{$diameter};
		--radius: #{$radius};
		--border: #{$diameter * $ratio-border};
	}

	// Update this using only 1 loop
	@for $i from 0 to $length {
		$x: ($i - $indice) * $space;

		@for $j from 0 to $length {
			$y: ($j - $indice) * $space;

			@for $k from 0 to $length {
				$z: ($k - $indice) * $space;

				$index: $i * $length + $k * $grid + $j + 1;

				#{$selector}:nth-child(#{$index}) {
					@if $random-color {
						$color: random-color();

						--color-border: #{rgba($color, $opacity-border)};

						@if $show-face {
							--color-face: #{rgba($color, $opacity-face)};
						}
					} @else {
						--color-border: #{rgba(
								if($random-border, random-color(), $color-border),
								$opacity-border
							)};

						@if $show-face {
							--color-face: #{rgba(
									if($random-face, random-color(), $color-face),
									$opacity-face
								)};
						}
					}

					transform: translate3d($x, $y, $z + $radius);
				}
			}
		}
	}
}

@keyframes rotate {
	0%,
	25% {
		transform: rotate3d(0, 0, 0, 0);
	}
	75%,
	100% {
		transform: rotate3d(1, 1, 0, 360deg);
	}
}

@keyframes translate {
	0%,
	100% {
		transform: translate3d(0, 0, var(--distance-front));
	}
	50% {
		transform: translate3d(0, 0, var(--distance-back));
	}
}

%center {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-direction: column;
}

*,
*::after,
*::before {
	margin: 0;
	border: 0;
	padding: 0;
	box-sizing: border-box;
}

body {
	@extend %center;

	height: 100vh;
	width: 100vw;
	position: relative;
	overflow: hidden;
	transform-style: preserve-3d;
	perspective: var(--perspective);
	background-color: $color-background;
}

section {
	transform-style: preserve-3d;
	animation: translate $time ease-in-out infinite;
}

ul {
	@extend %center;

	transform-style: preserve-3d;
	animation: rotate $time ease-in-out infinite;
}

li,
div {
	@extend %center;

	transform-style: preserve-3d;

	&,
	&::after,
	&::before {
		height: var(--diameter);
		width: var(--diameter);
		position: absolute;
		transform-origin: center center calc(-1 * #{var(--radius)});
		border: var(--border) solid var(--color-border);
		background-color: var(--color-face);
		backface-visibility: if($hide-backface, hidden, null);
	}

	&::after,
	&::before {
		content: "";
	}
}

li {
	&::after {
		transform: rotate3d(1, 0, 0, 90deg);
	}

	&::before {
		transform: rotate3d(-1, 0, 0, 90deg);
	}
}

div {
	transform: rotate3d(0, 1, 0, 180deg);

	&::after {
		transform: rotate3d(0, 1, 0, 90deg);
	}

	&::before {
		transform: rotate3d(0, -1, 0, 90deg);
	}
}

@include cube-world();
View Compiled
// You can play with it using the different settings in the CSS section.

(() => {
	const root = document.documentElement;

	const style = getComputedStyle(root);

	const length = style.getPropertyValue("--length");

	const scene = document.createElement("section");
	const world = document.createElement("ul");
	const cube = document.createElement("li");

	cube.appendChild(document.createElement("div"));

	const cubes = Array.from({ length }, () => cube.cloneNode(true));

	document.body
		.appendChild(scene)
		.appendChild(world)
		.append(...cubes);
})();

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.