Yarden A
Yarden A

Reputation: 45

Problem stacking CSS 3d cubes on top of each other

I am trying to pile up CSS 3D cubes on top of each other (my end goal is to build a Rubik's cube). I've started with 3 cubes placed like this: rotateX(0deg)

But this is what happens when i rotate it 45 degrees: rotateX(45deg)

This is the code:

* {
  box-sizing: border-box;
}

 :root {
  --cubeSize: 100px;
  --translateSize: 50px;
  --negTranslateSize: -50px;
}

.RCContainer {
  height: 300px;
  width: 100px;
  perspective: 600px;
}

.RC {
  position: relative;
  left: 450px;
  top: 200px;
  height: 300px;
  width: 100px;
  transform-style: preserve-3d;
  transform: rotateX(0deg);
}

.cubeContainer1,
.cubeContainer2,
.cubeContainer3 {
  height: var(--cubeSize);
  width: var(--cubeSize);
  position: relative;
}

.cubeContainer1 {
  position: absolute;
  top: 200px;
}

.cubeContainer2 {
  position: absolute;
  top: 100px;
}

.cubeContainer3 {
  position: absolute;
}

.cube {
  position: relative;
  height: var(--cubeSize);
  width: var(--cubeSize);
  transform-style: preserve-3d;
  transform: translateZ(var(--negTranslateSize)) rotateX(0deg);
}

.square {
  position: absolute;
  height: var(--cubeSize);
  width: var(--cubeSize);
  border: 3px solid black;
}

.front {
  transform: translateZ(var(--translateSize));
}

.back {
  transform: rotateX(180deg) translateZ(var(--translateSize));
}

.top {
  transform: rotateX(90deg) translateZ(var(--translateSize));
}

.bottom {
  transform: rotateX(-90deg) translateZ(var(--translateSize));
}

.left {
  transform: rotateY(-90deg) translateZ(var(--translateSize));
}

.right {
  transform: rotateY(90deg) translateZ(var(--translateSize));
}
<div class="RCContainer">
  <div class="RC">
    <div class="cubeContainer1">
      <div class="cube">
        <div class="square front blue"></div>
        <div class="square back black"></div>
        <div class="square top black"></div>
        <div class="square bottom red"></div>
        <div class="square left white"></div>
        <div class="square right black"></div>
      </div>
    </div>
    <div class="cubeContainer2">
      <div class="cube">
        <div class="square front blue"></div>
        <div class="square back black"></div>
        <div class="square top black"></div>
        <div class="square bottom black"></div>
        <div class="square left white"></div>
        <div class="square right black"></div>
      </div>
    </div>
    <div class="cubeContainer3">
      <div class="cube">
        <div class="square front blue"></div>
        <div class="square back black"></div>
        <div class="square top orange"></div>
        <div class="square bottom black"></div>
        <div class="square left white"></div>
        <div class="square right black"></div>
      </div>
    </div>
  </div>
</div>

Before I used position absolute on the cube containers I also tried playing with z-index a little bit on each of the cube containers but it didn't fix the problem.

How can I fix this?

Upvotes: 2

Views: 366

Answers (1)

Łukasz Blaszyński
Łukasz Blaszyński

Reputation: 1565

* {
  box-sizing: border-box;
}

 :root {
  --cubeSize: 100px;
  --translateSize: 50px;
  --negTranslateSize: -50px;
}

.RCContainer {
  height: 300px;
  width: 100px;
  perspective: 600px;
}

.RC {
  position: relative;
  left: 450px;
  top: 200px;
  height: 300px;
  width: 100px;
  transform-style: preserve-3d;
  transform: rotatex(30deg);
}

.cubeContainer1,
.cubeContainer2,
.cubeContainer3 {
  height: var(--cubeSize);
  width: var(--cubeSize);
  position: relative;
  transform-style: preserve-3d;
 }

.cubeContainer1 {
  position: absolute;
  top: 200px;
}

.cubeContainer2 {
  position: absolute;
  top: 100px;
}

.cubeContainer3 {
  position: absolute;
}

.cube {
  position: relative;
  height: var(--cubeSize);
  width: var(--cubeSize);
  transform-style: preserve-3d;
  transform: translateZ(var(--negTranslateSize)) rotateX(0deg);

}

.square {
  position: absolute;
  height: var(--cubeSize);
  width: var(--cubeSize);
  border: 3px solid black;
  transform-style: preserve-3d;
}

.front {
  transform: translateZ(var(--translateSize));
  background: red;
}

.back {
  transform: rotateX(180deg) translateZ(var(--translateSize));
   background: green;
}

.top {
  transform: rotateX(90deg) translateZ(var(--translateSize));
     background: yellow;

}



.left {
  transform: rotateY(-90deg) translateZ(var(--translateSize));
  background: blue;
}

.right {
  transform: rotateY(90deg) translateZ(var(--translateSize));
   background: cyan;
}

.bottom {
  transform: rotateX(-90deg) translateZ(var(--translateSize));
   background: pink;
}
<div class="RCContainer">
  <div class="RC">
    <div class="cubeContainer1">
      <div class="cube">
        <div class="square front blue"></div>
        <div class="square back black"></div>
        <div class="square top black"></div>
        <div class="square bottom red"></div>
        <div class="square left white"></div>
        <div class="square right black"></div>
      </div>
    </div>
    <div class="cubeContainer2">
      <div class="cube">
        <div class="square front blue"></div>
        <div class="square back black"></div>
        <div class="square top black"></div>
        <div class="square bottom black"></div>
        <div class="square left white"></div>
        <div class="square right black"></div>
      </div>
    </div>
    <div class="cubeContainer3">
      <div class="cube">
        <div class="square front blue"></div>
        <div class="square back black"></div>
        <div class="square top orange"></div>
        <div class="square bottom black"></div>
        <div class="square left white"></div>
        <div class="square right black"></div>
      </div>
    </div>
  </div>
</div>

Add transform-style: preserve-3d for all cubeContainers. Cube containers are also rotated because its parent is rotated, and without this property they use html elements ordering and overlaps after rotatating over x axis.

Upvotes: 1

Related Questions