Search code examples
css3dflipperspective

CSS perspective for each element


I am using a list of cards that can be flipped on click to show additional information. I would like to add some perspective to make it look nice.

My problem is that to give the list some perspective I need to attach the perspective to the ul element. The origin is then defined by the size of the parent what makes the element in the middle turn without perspective while the ones on top and bottom are transformed in a very ugly way.

Is there a way to give each element it's own perspective to have a smooth 3D look, Preferably without JavaScript?

ul {
  perspective: 600px;
}
li {
  list-style: none;
  width: 100px;
  height: 100px;
  margin: 5px;
  background-color: lightgrey;
  transition: all .3s ease;
}
li:hover {
  transform: rotateY(180deg);
}
<body>
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
  </ul>

</body>


Solution

  • Is there a way to give each element it's own perspective

    I don't know if I understood your question correctly but I think the below is what you're looking for. By giving the perspective value along with the transform property, you are directly giving it to each of the element (instead of creating a 3d space like it does when you set perspective property on ul).

    This means that each element whether it is the first or is in the middle or is at the last will rotate in the same way as the other.

    The perspective is applied to the un-hovered or the default state (li selector) also since the reverse transition should also happen properly. If this is not set, (a) the perspective won't get applied properly during the hover out and (b) sometimes it causes a jerky movement during quick hover-in-out.

    You can find more information in this CSS Tricks article. As you can see in the demo there, when the perspective is assigned directly on the children, each of them look the same unlike when it is applied on the parent.

    (Note: (1) I have changed the transition duration a bit just for the demo. (2) You'd have to play around with the perspective value to get the exact effect that you're looking for. I'd leave the tuning to you.)

    li {
      list-style: none;
      width: 100px;
      height: 100px;
      margin: 5px;
      background-color: lightgrey;
      transition: all 1s ease;
      transform: perspective(125px) rotateY(0deg);
    }
    li:hover {
      transform: perspective(125px) rotateY(180deg);
    }
    <body>
      <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
      </ul>
    
    </body>