CSS CSS Transitions and Transforms Adding 3D Effects with CSS Build a Rotating 3D Cube

Bartłomiej Wilczyński
Bartłomiej Wilczyński
6,269 Points

So I have the problem with images shining throw each other

Here is my CSS code, I did everything excatly like the Guil said but the images are shining through each other. What is wrong?

/* ================================= 
  Button Transitions
==================================== */

.button {
    transition: background .3s;
}
.button:hover {
    background: rgba(74,137,202, 1);
}

/* ================================= 
  Photo 3D Transforms & Transitions
==================================== */

.cube-container {
    box-shadow: 0 18px 40px 5px rgba(0,0,0,.4);
  perspective: 800px;
}

.photo-cube {
  transition: transform 2s ease-in-out;
  width: 220px;
  height: 200px;
  transform-style: preserve-3d;
}

.photo-cube:hover {
  transform: rotateY(-270deg);
}

.front,
.back,
.left,
.right {
  width: 100%;
  height: 100%;
  display:block;
  position:absolute;
  backface-visibility: hidden;
}

.front {
  transform: translateZ(110px);
}

.back {
  transform: translateZ(-110px) rotateY(270deg);
  transform-origin: center left;

}

.left {
  transform: rotateY(-270deg) translateX(110px);
  transform-origin: top right;
}

.right {
  transform: translateZ(-110px) rotate(180deg);
}
Jesse Cleary-Budge
seal-mask
.a{fill-rule:evenodd;}techdegree
Jesse Cleary-Budge
Front End Web Development Techdegree Student 8,593 Points

The solution as given by Guil is not working as of 7/10/2020 in the current version of Opera (69.0.3686.57). Ryan Markey's solution worked for me. Thanks, Ryan!

4 Answers

Steven Parker
Steven Parker
203,162 Points

That opacity trick is just a hack that conceals the real issue, which can be resolved just by changing the type of transform being used.. Just convert the three lines shown here and your transitions will work exactly as intended with no other changes:

.front {                                                                                                
/*transform: translateZ(110px);            <- change this... */
  transform: translate3d(0, 0, 110px);  /* <- ...to this     */
}

.left {
/*transform: rotateY(-270deg) translateX(110px);            <- change this... */
  transform: rotateY(-270deg) translate3d(110px, 0, 0);  /* <- ...to this     */
  transform-origin: top right;                                                                          
}

.right {
/*transform: translateZ(-110px) rotate(180deg);      <- change this... */
  transform: translateZ(-110px) rotateY(180deg);  /* <- ...to this     */
}
Steven Parker
Steven Parker
203,162 Points

Clearly, setting "opacity" to .99 (instead of the default of 1) is not genuinely intended to change the opacity. But it causes a side-effect of altering what is known as the stacking context of the element, which changes the rendering order. This causes the elements to be rendered in layers instead of conforming to the 3-D perspective space (which is the point of the exercise).

For the technical details, see the MDN page on The stacking context and related pages linked from it.

Maya Liberman
Maya Liberman
Full Stack JavaScript Techdegree Graduate 26,360 Points

Unfortunately you solution does not work with not using the opacity. Any idea why?

.cube-container { box-shadow: 0 18px 40px 5px rgba(0, 0, 0, 0.4); perspective: 800px; }

.photo-cube { transition: transform 2s ease-in-out; width: 220px; height: 220px; transform-style: preserve-3d; }

.photo-cube:hover { transform: rotateY(-270deg); }

.front, .back, .left, .right { width: 100%; height: 100%; display: block; position: absolute; opacity: 0.99; }

.front { /transform: translateZ(110px); <- change this... */ transform: translate3d(0, 0, 110px); / <- ...to this */ }

.back { transform: translateZ(-110px) rotateY(270deg); transform-origin: center left;

}

.left { /transform: rotateY(-270deg) translateX(110px); <- change this... */ transform: rotateY(-270deg) translate3d(110px, 0, 0); / <- ...to this */ transform-origin: top right; }

.right { /transform: translateZ(-110px) rotate(180deg); <- change this... */ transform: translateZ(-110px) rotateY(180deg); / <- ...to this */ }

Here is a solution from a previous post . Instead of backface-visibility: hidden; try opacity: 0.99; in interactions.css.

.front,
.back,
.left,
.right {
  width: 100%;
  height: 100%;
  display:block;
  position:absolute;
  opacity: 0.99;
}
Daniel Tafvelin
Daniel Tafvelin
4,833 Points

The best way i managed to solve it was by doing the following:

.front, .back, .left, .right { width: 100%; height: 100%; display: block; position: absolute; }

I added the "transform-style: preserve-3d;" and "backface-visibility: hidden;" properties to the above CSS and that fixed it for me.

Steven Parker
Steven Parker
203,162 Points

Those properties are both in the original code above.
Did you add them in different places than where they are shown here?

Daniel Tafvelin
Daniel Tafvelin
4,833 Points

If i remember correctly Guil adds those properties to the parent container. But I also added them to the code i posted above (making it ".front, .back, .left, .right { width: 100%; height: 100%; display: block; position: absolute; transform-style: preserve-3d; backface-visibility: hidden;}") and that solved the problem.

Steven Parker
Steven Parker
203,162 Points

The "preserve-3d" setting can go on the container, it doesn't need to be applied to each object inside it.

Daniel Tafvelin
Daniel Tafvelin
4,833 Points

Well when I only had it in the container I got the same error that this thread has reported, and when I added it to the other object it fixed it. I tried all the other solutions mentioned in this thread and none of them worked except for the opacity-trick but as you said, that only conceals the real issue.

Cameron Cochran
Cameron Cochran
Front End Web Development Techdegree Student 8,781 Points
<p>/* ================================= 
  Photo 3D Transforms & Transitions
==================================== */

.cube-container {
    box-shadow: 0 18px 40px 5px rgba(0,0,0,.4);
  perspective: 800px;
}

.photo-cube {
  transition: transform 2s ease-in-out;
  width: 220px;
  height: 200px;
  transform-style: preserve-3d;
}

.photo-cube:hover {
  transform: rotateY(-270deg);
}

.front,
.back,
.left,
.right {
  width: 100%;
  height: 100%;
  display:block;
  position:absolute;
  opacity: 0.99;
}

.front {
  transform: translate3d(0,0, 110px);
}

.back {
  transform: translateZ(-110px) rotateY(270deg);
  transform-origin: center left;

}

.left {
  transform: rotateY(-270deg) translate3d(110px, 0 0);
  transform-origin: top right;
}

.right {
  transform: translateZ(-110px) rotate(180deg);
}<p>
Cameron Cochran
Cameron Cochran
Front End Web Development Techdegree Student 8,781 Points

^^ I am sure there is a bug somewhere but I tried Steven's solution and it didn't work. (ignore the <p> elements at the start and finish...I misunderstood how to format the code when using this message board). The opacity hack did work for me...I'd love some explanation of what is going on. I am a little confused and I am really digging these concepts.

Steven Parker
Steven Parker
203,162 Points

Those "<p>"'s are HTML code and don't being in the CSS flie. They also invalidate some of the CSS rules and cause them to be ignored.