<div class="cube"></div>
* {
    box-sizing: border-box;
}
body {
    margin: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100vw;
    height: 100vh;
    background-color: #333;
    align-items: center;
    justify-content: center;
    perspective: 1200px;
}

:root {
    --color1: lightgreen;
    --color2: salmon;
    --color3: yellow;
    --cube-size: 100px;

    --normals-camera-x: 0;
    --normals-camera-y: 0;
    --normals-camera-z: 1; /* Changed from -1 to 1 */

    --normals-front-x: 0;
    --normals-front-y: 0;
    --normals-front-z: 1;
    --normals-back-x: 0;
    --normals-back-y: 0;
    --normals-back-z: -1;
    --normals-right-x: 1;
    --normals-right-y: 0;
    --normals-right-z: 0;
    --normals-left-x: -1;
    --normals-left-y: 0;
    --normals-left-z: 0;
    --normals-top-x: 0;
    --normals-top-y: 1;
    --normals-top-z: 0;
    --normals-bottom-x: 0;
    --normals-bottom-y: -1;
    --normals-bottom-z: 0;

    --inX: 0;
    --inY: 0;
    --inZ: 0;

    --rotX: mod(var(--inX), 360);
    --rotY: mod(var(--inY), 360);
    --rotZ: mod(var(--inZ), 360);
    --rad: calc(3.14 / 180);

    --xRot: calc(var(--rotX) * 1deg);
    --yRot: calc(var(--rotY) * 1deg);
    --zRot: calc(var(--rotZ) * 1deg);

    --front-y1: calc(
        (var(--normals-front-y) * cos(var(--xRot))) -
            (var(--normals-front-z) * sin(var(--xRot)))
    );
    --front-z1: calc(
        var(--normals-front-y) * sin(var(--xRot)) + var(--normals-front-z) *
            cos(var(--xRot))
    );
    --front-x2: calc(
        var(--normals-front-x) * cos(var(--yRot)) + var(--front-z1) *
            sin(var(--yRot))
    );
    --front-z2: calc(
        var(--normals-front-x) * -1 * sin(var(--yRot)) + var(--front-z1) *
            cos(var(--yRot))
    );
    --front-x3: calc(
        var(--front-x2) * cos(var(--zRot)) - var(--front-y1) * sin(var(--zRot))
    );
    --front-y3: calc(
        var(--front-x2) * sin(var(--zRot)) + var(--front-y1) * cos(var(--zRot))
    );
    --front-x: var(--front-x3);
    --front-y: var(--front-y3);
    --front-z: var(--front-z2);

    --back-y1: calc(
        (var(--normals-back-y) * cos(var(--xRot))) -
            (var(--normals-back-z) * sin(var(--xRot)))
    );
    --back-z1: calc(
        var(--normals-back-y) * sin(var(--xRot)) + var(--normals-back-z) *
            cos(var(--xRot))
    );
    --back-x2: calc(
        var(--normals-back-x) * cos(var(--yRot)) + var(--back-z1) *
            sin(var(--yRot))
    );
    --back-z2: calc(
        var(--normals-back-x) * -1 * sin(var(--yRot)) + var(--back-z1) *
            cos(var(--yRot))
    );
    --back-x3: calc(
        var(--back-x2) * cos(var(--zRot)) - var(--back-y1) * sin(var(--zRot))
    );
    --back-y3: calc(
        var(--back-x2) * sin(var(--zRot)) + var(--back-y1) * cos(var(--zRot))
    );
    --back-x: var(--back-x3);
    --back-y: var(--back-y3);
    --back-z: var(--back-z2);

    --right-y1: calc(
        (var(--normals-right-y) * cos(var(--xRot))) -
            (var(--normals-right-z) * sin(var(--xRot)))
    );
    --right-z1: calc(
        var(--normals-right-y) * sin(var(--xRot)) + var(--normals-right-z) *
            cos(var(--xRot))
    );
    --right-x2: calc(
        var(--normals-right-x) * cos(var(--yRot)) + var(--right-z1) *
            sin(var(--yRot))
    );
    --right-z2: calc(
        var(--normals-right-x) * -1 * sin(var(--yRot)) + var(--right-z1) *
            cos(var(--yRot))
    );
    --right-x3: calc(
        var(--right-x2) * cos(var(--zRot)) - var(--right-y1) * sin(var(--zRot))
    );
    --right-y3: calc(
        var(--right-x2) * sin(var(--zRot)) + var(--right-y1) * cos(var(--zRot))
    );
    --right-x: var(--right-x3);
    --right-y: var(--right-y3);
    --right-z: var(--right-z2);

    --left-y1: calc(
        (var(--normals-left-y) * cos(var(--xRot))) -
            (var(--normals-left-z) * sin(var(--xRot)))
    );
    --left-z1: calc(
        var(--normals-left-y) * sin(var(--xRot)) + var(--normals-left-z) *
            cos(var(--xRot))
    );
    --left-x2: calc(
        var(--normals-left-x) * cos(var(--yRot)) + var(--left-z1) *
            sin(var(--yRot))
    );
    --left-z2: calc(
        var(--normals-left-x) * -1 * sin(var(--yRot)) + var(--left-z1) *
            cos(var(--yRot))
    );
    --left-x3: calc(
        var(--left-x2) * cos(var(--zRot)) - var(--left-y1) * sin(var(--zRot))
    );
    --left-y3: calc(
        var(--left-x2) * sin(var(--zRot)) + var(--left-y1) * cos(var(--zRot))
    );
    --left-x: var(--left-x3);
    --left-y: var(--left-y3);
    --left-z: var(--left-z2);

    --top-y1: calc(
        (var(--normals-top-y) * cos(var(--xRot))) -
            (var(--normals-top-z) * sin(var(--xRot)))
    );
    --top-z1: calc(
        var(--normals-top-y) * sin(var(--xRot)) + var(--normals-top-z) *
            cos(var(--xRot))
    );
    --top-x2: calc(
        var(--normals-top-x) * cos(var(--yRot)) + var(--top-z1) *
            sin(var(--yRot))
    );
    --top-z2: calc(
        var(--normals-top-x) * -1 * sin(var(--yRot)) + var(--top-z1) *
            cos(var(--yRot))
    );
    --top-x3: calc(
        var(--top-x2) * cos(var(--zRot)) - var(--top-y1) * sin(var(--zRot))
    );
    --top-y3: calc(
        var(--top-x2) * sin(var(--zRot)) + var(--top-y1) * cos(var(--zRot))
    );
    --top-x: var(--top-x3);
    --top-y: var(--top-y3);
    --top-z: var(--top-z2);

    --bottom-y1: calc(
        (var(--normals-bottom-y) * cos(var(--xRot))) -
            (var(--normals-bottom-z) * sin(var(--xRot)))
    );
    --bottom-z1: calc(
        var(--normals-bottom-y) * sin(var(--xRot)) + var(--normals-bottom-z) *
            cos(var(--xRot))
    );
    --bottom-x2: calc(
        var(--normals-bottom-x) * cos(var(--yRot)) + var(--bottom-z1) *
            sin(var(--yRot))
    );
    --bottom-z2: calc(
        var(--normals-bottom-x) * -1 * sin(var(--yRot)) + var(--bottom-z1) *
            cos(var(--yRot))
    );
    --bottom-x3: calc(
        var(--bottom-x2) * cos(var(--zRot)) - var(--bottom-y1) *
            sin(var(--zRot))
    );
    --bottom-y3: calc(
        var(--bottom-x2) * sin(var(--zRot)) + var(--bottom-y1) *
            cos(var(--zRot))
    );
    --bottom-x: var(--bottom-x3);
    --bottom-y: var(--bottom-y3);
    --bottom-z: var(--bottom-z2);

    /*    normalise "function"  */
    --magnitude-cam: sqrt(
        calc(
            (var(--normals-camera-x) * var(--normals-camera-x)) +
                (var(--normals-camera-y) * var(--normals-camera-y)) +
                (var(--normals-camera-z) * var(--normals-camera-z))
        )
    );
    --normalised-cam-x: var(--normals-camera-x) / var(--magnitude-cam);
    --normalised-cam-y: var(--normals-camera-y) / var(--magnitude-cam);
    --normalised-cam-z: var(--normals-camera-z) / var(--magnitude-cam);

    /*    dot product "function"  */
    --dot-prod-front: calc(
        (var(--normals-camera-x) * var(--front-x)) +
            (var(--normals-camera-y) * var(--front-y)) +
            (var(--normals-camera-z) * var(--front-z))
    );
    --dot-prod-back: calc(
        (var(--normals-camera-x) * var(--back-x)) +
            (var(--normals-camera-y) * var(--back-y)) +
            (var(--normals-camera-z) * var(--back-z))
    );
    --dot-prod-right: calc(
        (var(--normals-camera-x) * var(--right-x)) +
            (var(--normals-camera-y) * var(--right-y)) +
            (var(--normals-camera-z) * var(--right-z))
    );
    --dot-prod-left: calc(
        (var(--normals-camera-x) * var(--left-x)) +
            (var(--normals-camera-y) * var(--left-y)) +
            (var(--normals-camera-z) * var(--left-z))
    );
    --dot-prod-top: calc(
        (var(--normals-camera-x) * var(--top-x)) +
            (var(--normals-camera-y) * var(--top-y)) +
            (var(--normals-camera-z) * var(--top-z))
    );
    --dot-prod-bottom: calc(
        (var(--normals-camera-x) * var(--bottom-x)) +
            (var(--normals-camera-y) * var(--bottom-y)) +
            (var(--normals-camera-z) * var(--bottom-z))
    );

    /* display switches */
    --X-above-90: Min(1, Max(calc(var(--rotX) - 90), 0));
    --X-below-90: calc(1 - var(--X-above-90));
    --X-above-270: Min(1, Max(calc(var(--rotX) - 270), 0));
    --X-below-270: calc(1 - var(--X-above-270));
    --X-between-90-270: Max(0, 1 - Max(var(--X-below-90), var(--X-above-270)));
    --X-Not-between-90-270: calc(1 - var(--X-between-90-270));

    --Y-above-90: Min(1, Max(calc(var(--rotY) - 90), 0));
    --Y-below-90: calc(1 - var(--Y-above-90));
    --Y-above-270: Min(1, Max(calc(var(--rotY) - 270), 0));
    --Y-below-270: calc(1 - var(--Y-above-270));
    --Y-between-90-270: Max(0, 1 - Max(var(--Y-below-90), var(--Y-above-270)));
    --Y-Not-between-90-270: calc(1 - var(--Y-between-90-270));

    --show-front: Min(
        1,
        Max(calc(var(--dot-prod-front) * 100 - var(--dot-prod-back) * 100), 0)
    );
    --show-back: calc(1 - var(--show-front));
    --show-right-dot: Min(
        1,
        Max(calc(var(--dot-prod-right) * 100 - var(--dot-prod-left) * 100), 0)
    );
    --show-left-dot: calc(1 - var(--show-right-dot));
    --show-right: calc(
        var(--show-right-dot) * var(--X-Not-between-90-270) +
            var(--show-left-dot) * var(--X-between-90-270)
    );
    --show-left: calc(1 - var(--show-right));
    --show-top-dot: Min(
        1,
        Max(calc(var(--dot-prod-top) * 100 - var(--dot-prod-bottom) * 100), 0)
    );
    --show-bottom-dot: calc(1 - var(--show-top-dot));
    --show-top: calc(
        var(--show-top-dot) * var(--Y-Not-between-90-270) +
            var(--show-bottom-dot) * var(--Y-between-90-270)
    );
    --show-bottom: calc(1 - var(--show-top));
}
/* =====================================================
   THE CUBE (SINGLE DIV WITH ::before AND ::after)
   =====================================================
   Here we “center” the cube using translate(-50%, -50%) but then add
   computed offsets (via translate3d) so that its “center” moves based on
   --show-front, --show-left and --show-top. Finally, we rotate it using
   --rotX, --rotY and --rotZ and then (for each face) offset that face from
   the computed cube–center.
*/
.cube {
    position: absolute;
    left: 50%;
    top: 50%;
    width: var(--cube-size);
    height: var(--cube-size);
    transform-style: preserve-3d;
    transform: translate(-50%, -50%) rotateX(calc(var(--rotX) * 1deg))
        rotateY(calc(var(--rotY) * 1deg)) rotateZ(calc(var(--rotZ) * 1deg))
        translateZ(
            calc(
                (var(--show-front) - var(--show-back)) * var(--cube-size) * 0.5
            )
        );
    background: var(--color1);
    animation: spin 4s linear;
}

/* Side face (using ::before) – we want it to follow the same computed offset as the cube */
.cube::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: var(--cube-size);
    height: var(--cube-size);
    transform-style: preserve-3d;
    transform: translate(-50%, 0%)
        translateZ(
            calc(
                -1 * (var(--show-front) - var(--show-back)) * var(--cube-size) /
                    2
            )
        )
        rotateY(90deg) translateZ(calc(var(--show-right) * var(--cube-size)));
    background: var(--color2);
}

/* Top face (using ::after) – again, include the computed offset */
.cube::after {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: var(--cube-size);
    height: var(--cube-size);
    transform-style: preserve-3d;
    transform: translate(0%, -50%)
        /* Compensate for main cube's Z translation */
        translateZ(
            calc(
                -1 * (var(--show-front) - var(--show-back)) * var(--cube-size) /
                    2
            )
        )
        /* Position top face */ rotateX(-90deg)
        translateZ(calc(var(--show-top) * var(--cube-size)));
    background: var(--color3);
}

let x = 0;
let y = 0;

const root = document.querySelector(':root');

setInterval(rotateX, 50)
setInterval(rotateY, 30)

function rotateX(){
    root.style.setProperty('--inX', x);
    x = x + 2.4;
}

function rotateY(){
    root.style.setProperty('--inY', y);
    y = y + 2.1;
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.