<div class="container-scene">
  <div class="cube">
    <div class="face-1"></div>
    <div class="face-2"></div>
    <div class="face-3"></div>
    <div class="face-4"></div>
    <div class="face-5"></div>
    <div class="face-6"></div>
  </div>
</div>
:root {
  --scenePerspective: 400;
  --cubeRotateY: -45;
  --cubeRotateX: 0;
  --perspectiveOriginX: 50;
  --perspectiveOriginY: 50;
  --cubeTranslateZ: -100;
  --cubeFacesTranslateZ: 100;
}

.container-scene {
  width: 200px;
  height: 200px;
  perspective: calc(var(--scenePerspective) * 1px);
  perspective-origin: calc(var(--perspectiveOriginX) * 1%) calc(var(--perspectiveOriginY) * 1%);
}

.cube {
  width: 200px;
  height: 200px;
  position: relative;
  transform-style: preserve-3d;
  transform: translateZ(calc(var(--cubeTranslateZ) * 1px)) rotateY(calc(var(--cubeRotateY) * 1deg)) rotateX(calc(var(--cubeRotateX) * 1deg));
  
  div[class^='face-'], div[class*=' face-']{
    width: 100%;
    height: 100%;
    position: absolute;
    backface-visibility: inherit;
    border: 1px solid hsl(0,0,0);
  }
  
  .face-1 {
    transform: rotateY(0deg) translateZ(calc(var(--cubeFacesTranslateZ) * 1px));
  }
  
  .face-2 {
    transform: rotateY(180deg) translateZ(calc(var(--cubeFacesTranslateZ) * 1px));
  }
  
  .face-3 {
    transform: rotateY(90deg) translateZ(calc(var(--cubeFacesTranslateZ) * 1px));
  }
  
  .face-4 {
    transform: rotateY(-90deg) translateZ(calc(var(--cubeFacesTranslateZ) * 1px));
  }
  
  .face-5 {
    transform: rotateX(90deg) translateZ(calc(var(--cubeFacesTranslateZ) * 1px));
  }
  
  .face-6 {
    transform: rotateX(-90deg) translateZ(calc(var(--cubeFacesTranslateZ) * 1px));
  }
}


///-------------


* { box-sizing: border-box; }

body {
  background-color: hsl(231, 15%, 18%);
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

  @for $i from 1 through 6 {
    .face-#{$i}{
      background-color: hsla(360 - $i * 60, 100%, 74%, 0.6);
      &::after {
        content: "#{$i}";
        font-size: 4rem;
        color: white;
      }
    }
  }
View Compiled
class Cube {
  constructor() {
    this.scenePerspective = parseFloat(getComputedStyle(document.documentElement).getPropertyValue("--scenePerspective"));
    this.cubeRotateY = parseFloat(getComputedStyle(document.documentElement).getPropertyValue("--cubeRotateY"));
    this.cubeRotateX = parseFloat(getComputedStyle(document.documentElement).getPropertyValue("--cubeRotateX"));
    this.perspectiveOriginX = parseFloat(getComputedStyle(document.documentElement).getPropertyValue("--perspectiveOriginX"));
    this.perspectiveOriginY = parseFloat(getComputedStyle(document.documentElement).getPropertyValue("--perspectiveOriginY"));
    this.cubeTranslateZ = parseFloat(getComputedStyle(document.documentElement).getPropertyValue("--cubeTranslateZ"));
    this.cubeFacesTranslateZ = parseFloat(getComputedStyle(document.documentElement).getPropertyValue("--cubeFacesTranslateZ"));
    this.preserve3d = true;
  }
}

window.onload = function() {
  const cube = new Cube();
  const gui = new dat.GUI();
  const controllersCSS = {
    cubeTranslateZ: gui.add(cube, "cubeTranslateZ"),
    cubeFacesTranslateZ: gui.add(cube, "cubeFacesTranslateZ"),
    perspectiveOriginX: gui.add(cube, "perspectiveOriginX", -200, 300),
    perspectiveOriginY: gui.add(cube, "perspectiveOriginY", -200, 300),
    scenePerspective: gui.add(cube, "scenePerspective", 0, 4000),
    cubeRotateY: gui.add(cube, "cubeRotateY", -360, 360),
    cubeRotateX: gui.add(cube, "cubeRotateX", -360, 360)
  };

  for (let key in controllersCSS) {
    controllersCSS[key].onChange(value => {
      document.documentElement.style.setProperty(`--${key}`, value);
    });
  }
};
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.5/dat.gui.min.js