2

I'm not sure if I'm missing something with my understanding of translateZ and perspective but I've added a CodePen for the same.

Here's my code:

body {
  margin: 0;
  height: 100vh;
}

.cards-container {
  padding: 100px;
  margin: auto;
  margin-top: 100px;
  transform-style: preserve-3d;
}

.cards-container,
.cards-container * {
  height: 400px;
  width: 400px;
  box-sizing: border-box;
  background-color: lightgray;
  transition: all ease 1.6s;
  /* perspective: 1200px; */
}

.card {
  width: 200px;
  height: 200px;
  padding: 50px;
  background-color: lime;
  transform-style: preserve-3d;
}

.card-child {
  width: 100px;
  height: 100px;
  background-color: rgb(255, 230, 0);
}

.cards-container:hover {
  transform: perspective(1200px) rotateX(50deg) rotateY(20deg) rotateZ(-35deg) translateZ(40px);
}

.cards-container:hover .card {
  transform: perspective(1200px) translateZ(80px);
}

.cards-container:hover .card .card-child {
  transform: perspective(1200px) translateZ(60px);
}
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Demo</title>
  <link rel="stylesheet" href="css/main.css">
</head>

<body>
  <script src="index.js"></script>
  <div class="cards-container">
    <div class="card">
      <div class="card-child"></div>
    </div>
  </div>
</body>

</html>

The issue I'm facing is one that I'm unable to consistently reproduce. If you hover over the cards in my example, you will notice the transitions play smoothly. The intended transition is for the 3 cards to go from a flat layout into a 3D one on hover, where each card raises above its parent. But sometimes when I hover over them, the transition goes all wonky and the whole card itself gets skewed/distorted, goes out of bounds in the z-axis. To reproduce this just try hovering on and off a couple of times over the card and you will notice it happen randomly.

In my opinion it seems to be something with the perspective but I'm out of my depth here considering I'm not even sure how to reproduce it consistently.

Any understanding of this issue is appreciated.

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Kuday
  • 68
  • 1
  • 6

1 Answers1

2

The trick is that you are also applying a transition to perspecitve since it's a part of the transformation creating this bad effect. Perspective need to remain the same even on the non hover state:

body {
  margin: 0;
  height: 100vh;
}

.cards-container {
  padding: 100px;
  margin: auto;
  margin-top: 100px;
  transform-style: preserve-3d;
}

.cards-container,
.cards-container * {
  height: 400px;
  width: 400px;
  box-sizing: border-box;
  background-color: lightgray;
  transition: all ease 1.6s;
  /* perspective: 1200px; */
}

.card {
  width: 200px;
  height: 200px;
  padding: 50px;
  background-color: lime;
  transform-style: preserve-3d;
}

.card-child {
  width: 100px;
  height: 100px;
  background-color: rgb(255, 230, 0);
}

.cards-container {
  transform: perspective(1200px) rotateX(0deg) rotateY(0deg) rotateZ(0deg) translateZ(0px);
}

.cards-container:hover {
  transform: perspective(1200px) rotateX(50deg) rotateY(20deg) rotateZ(-35deg) translateZ(40px);
}

.cards-container .card {
  transform: perspective(1200px) translateZ(0px);
}

.cards-container:hover .card {
  transform: perspective(1200px) translateZ(80px);
}

.cards-container .card .card-child {
  transform: perspective(1200px) translateZ(0px);
}

.cards-container:hover .card .card-child {
  transform: perspective(1200px) translateZ(60px);
}
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Demo</title>
  <link rel="stylesheet" href="css/main.css">
</head>

<body>
  <script src="index.js"></script>
  <div class="cards-container">
    <div class="card">
      <div class="card-child"></div>
    </div>
  </div>
</body>

</html>

In such case, it's better to consider the perspective property instead of perspective() transform function

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • 2 things: 1. The yellow card in your code snippet still seems to be acting weird although the rest of it seems fine now. 2. When you say its better to use the `perspective` property instead, can you help me understand how I'd use it? Or if you can direct me to some resources where I can understand the difference between the 2 better, that would be fine too. – Kuday Feb 09 '21 at 21:07
  • 1
    @Kuday (1) update the code, forget to remove the hover (2) it's better for this particular case because it will avoid you dealing with such issue since you can simply setup the perspective one time (https://jsfiddle.net/yvfb8zgj/ you did this in your old question). Here is some related questions: https://stackoverflow.com/a/51891547/8620333 / https://stackoverflow.com/q/63026056/8620333 – Temani Afif Feb 09 '21 at 21:27