CSS CSS Transitions and Transforms Adding 3D Effects with CSS Create a Flipping Animation with 3D Transform Properties

Nour El-din El-helw
Nour El-din El-helw
8,228 Points

trasnform-style

Do we declare the "transform-style" property to the 3d transformed element or to it's child that we want to be transformed in 3d space? Because here the 3d transformed element is ".photo-container" div and the child is ".photo div" but we declared it to ".photo div" so can someone please explain?

2 Answers

Balazs Pukli
Balazs Pukli
46,036 Points

From what I'm getting about all this, it does not matter that you don't loop through every generation of elements with this inheritance thing. For example, if you have a perspective for the grand-grandparent of an element, you don't have to declare the preserve-3d in the grandparents and parents if you don't need to. Just declare it multiple levels below where you will need it, and it will work. And the perspective will be shared among all elements, it will be a perspective declared in the original grand-grandmother.

Nour El-din El-helw
Nour El-din El-helw
8,228 Points

Oh, really good explanation. Thanks!

Balazs Pukli
Balazs Pukli
46,036 Points

I'm going to go from the outmost element to explain all functionality:

.content

  • The ".content" is a class for a div that contains all content which will be depicted in a 3D space, like a frame if you will. We use it to declare the prespective, like "how far" the object will look based on the angles they are depicted in. Every single one of its children would be a 3D object, but only its direct children. If we want to depict deeply nested children in 3D, we must pass down the 3D space using the transform-style property later. But this outer container with the declared perspective makes sure that all children will be depicted in the same 3D space, not as if they would be in many parallel 3D spaces.
.content {
   perspective: 700px;
}

.photo-container

  • The ".photo-container" is a class for the outside div of individual elements. It is only responsible to add space between the elements, so that they wouldn't be too close together.
.photo-container {
    text-align: center;
    margin-bottom: 2.5em;
}

.photo

  • The ".photo" class is for the inside div containing the 3D element. It is determined to be a parent for the 3D object by the the transform-style: preserve-3d property. This means that all of it's children will be depicted in 3d. These objects will be depicted in the same 3D space declared 2 levels above, the same perspective. The transform-style just passes down the functionality to affect direct children.
  • We add a transition with the transform parameter as well. This means that when we add the rotate transform on hover, that transform must be transitioned, instead of just changin in a blink of an eye.
  • Note that this element is transformed, even though it is invisible. What we will actually see is it's children transformed!
.photo {
   transform-style: preserve-3d;
   transition: transform 1s cubic-bezier(.55, -.62, .27, 1.2);  
}

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

.side-a and .side-b

  • Finally, the ".side-a" and ".side-b" classes are for the elements depicted in 3D. One of them is a div, another one is an img in this example.
  • Since these are already 3D objects thanks to their parent, we can hide their backfaces. (Only 3D objects have backfaces.)
  • We determine ".side-b" to be already rotated 180 degrees by default. This means that it will only show up, when we flip the parent element, as if it would be "on the other side".
.side-a, .side-b{
  backface-visibility: hidden;
}

.side-b{  
  transform: rotateY(180deg);
}
Nour El-din El-helw
Nour El-din El-helw
8,228 Points

Isn't .photo-container a direct child of .content, and .photo is a child of .photo-container so we should have declared transform-style: preserve-3d for it too right? Or is it because .photo-container doesn't have content so it is neglected and .photo is acts like a direct child of .content? Other than that everything is clear, thanks :)