Question

I am trying to create a menu with 4 buttons each with identical 3d effect on hover but it seems that the perspective is applied to parent element and not to individual elements.

Here is how it looks like:

enter image description here

The first element is actually hovered over (cursor got removed from screenshot).

HTML:

        <nav>
            <ul>
                <div><li>test1</li></div>
                <div><li>test2</li></div>
                <div><li>test3</li></div>
                <div><li>test4</li></div>
            </ul>
        </nav>

CSS:

nav{
  height: 100px;
}
nav div{
    -webkit-perspective: 200px;
  -moz-perspective: 200px;
  perspective: 200px;
}
nav ul li{
  width: 22%;
  height: 100%;
  float: left;
  margin: 0 1.5% 0 1.5%;
  padding: 0.6em 0;
  text-align: center;
  background: #BBCFCE;
  cursor: pointer;

  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  transform-style: preserve-3d;

  -webkit-transition: all 0.3s;
  -moz-transition: all 0.3s;
  transition: all 0.3s;
}
nav ul li:after{
  content: '';
  position: absolute;
  z-index: -1;

  width: 20%;
  height: 100%;
  left: -20%;
  top: 0;
  background: #54CED3;

  -webkit-transform-origin: 100% 0%;
  -webkit-transform: rotateY(-90deg);
  -moz-transform-origin: 100% 0%;
  -moz-transform: rotateY(-90deg);
  -ms-transform-origin: 100% 0%;
  -ms-transform: rotateY(-90deg);
  transform-origin: 100% 0%;
  transform: rotateY(-90deg);
}
nav ul li:hover{
  -webkit-transform: rotateY(15deg);
  -moz-transform: rotateY(15deg);
  -ms-transform: rotateY(15deg);
  transform: rotateY(15deg);
}

Same issue if I remove the div wrappers and apply perspective to li directly. If I dont use perspective at all I get even effect though the rotation is smaller and when the cursor moves over the right 50% of any li element it alternates from hover state nothing(effect changes as does the cursor pointer).

What am I doing wrong?

Was it helpful?

Solution

Your problem comes from sizing system, and not from the 3d transforms (mostly).

looking at your HTML, looks like you would have the ul divided in fours divs. But, the divs size is still the same of the ul, and it is at the children of these that you decide to set the width to 22%. That means that the size of the divs is misleading, and creates the error afterwards.

I have changed most of the dimesioning porperties from the li to the div:

nav{
  height: 100px;
}
nav div{
    -webkit-perspective: 200px;
  -moz-perspective: 200px;
  perspective: 200px;
    -webkit-perspective-origin: left center;
    -moz-perspective-origin: left center;
    perspective-origin: left center;
      width: 22%;
  height: 40px;
  float: left;
  margin: 0 1.5% 0 1.5%;
  padding: 0.6em 0;
  text-align: center;
}
nav ul li{
  height: 100%;

  background: #BBCFCE;
  cursor: pointer;

  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  transform-style: preserve-3d;

  -webkit-transition: all 0.3s;
  -moz-transition: all 0.3s;
  transition: all 0.3s;
}
nav ul li:after{
  content: '';
  position: absolute;
  z-index: -1;

  width: 20%;
  height: 100%;
  left: -20%;
  top: 0;
  background: #54CED3;

  -webkit-transform-origin: 100% 0%;
  -webkit-transform: rotateY(-90deg);
  -moz-transform-origin: 100% 0%;
  -moz-transform: rotateY(-90deg);
  -ms-transform-origin: 100% 0%;
  -ms-transform: rotateY(-90deg);
  transform-origin: 100% 0%;
  transform: rotateY(-90deg);
}
nav ul li:hover{
  -webkit-transform: rotateY(15deg);
  -moz-transform: rotateY(15deg);
  -ms-transform: rotateY(15deg);
  transform: rotateY(15deg);
}

Also, I understood that you wanted the pseudo element to show on the hover. To get this, I have set the perspective origin to the left; that way you see the element from the beginning

demo

By the way, 2 notes

1) The proper HTML styling is that the li are children of the ul. I mean direct descendants, not child of a child.

2) If you create a fiddle with your code, you will make it easier for other people to help you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top