CSS 3d transform perspective grid

Problem

Trying to create a block grid that is 3d transformed at some angle, then when you hover one of the elements it rotates in facing towards the user. Look below to see a not-very-well working example (Chrome only - does it work for Safari too?).

So I have a couple of problems with this I think you can notice them too, I hope they are solvable at all;

  • rotating the blocks towards the user doesnt work well. The perspective seems to be wrong: on the last rows it looks like its going to a different angle. And I need to also do a scale(1,1.9) which shouldn't be necessary I think, but else they all get a small height.
  • The perspective changes as you drag the screen to a smaller size...
  • Finally the animation (in my chrome) doesn't always go fluently. Sometimes it does, but on some occasions the block first stretches and then rotates at once

How to solve this? Or did anyone already build something like this before?

you can see what I mean here on jsfiddle (make the run-screen wide)

CSS:

body{
            -webkit-perspective: 1000;
            background:black;
            -webkit-background-size: cover;
            -moz-background-size: cover;
            -o-background-size: cover;
            background-size: cover;
        }
        #grid{
            margin:auto;
            width:840px;
            -webkit-transform: rotate3d(1,0,0, 70deg);
            margin-top:200px;
        }
        #grid>div{
            -webkit-perspective: 600;
            -moz-perspective: 600;
            perspective: 600;
            color:white;
            font-family:Arial;
            font-size:70px;
            line-height:140px;
            height:140px;
            width:140px;
            float:left;
            text-align:center;
            cursor:pointer;
            position:relative;
        }
        #grid div:hover{
            z-index:500;
        }
        #grid>div:hover div{
            -webkit-transform: rotate3d(1,0,0, -39deg) scale(1,1.9);
            -moz-transform: rotate3d(1,0,0, -39deg) scale(1,1.9);
            transform: rotate3d(1,0,0, -39deg) scale(1,1.9);
        }
        #grid>div>div{
            -webkit-transform-origin:50% 100%;
            width:100%;
            height:100%;
            -webkit-transition:-webkit-transform ease 0.5s;
            -moz-transition:-moz-transform ease 0.5s;
            transition:transform ease 0.5s;
        }
        #grid>div:nth-child(4n)>div{background:red;}
        #grid>div:nth-child(4n+1)>div{background:orange;}
        #grid>div:nth-child(4n+2)>div{background:blue;}
        #grid>div:nth-child(4n+3)>div{background:green;}

        #grid>div:nth-child(6n+1){-webkit-perspective-origin: 300% 100%;-moz-perspective-origin: 300% 100%;}
        #grid>div:nth-child(6n+2){-webkit-perspective-origin: 200% 100%;-moz-perspective-origin: 200% 100%;}
        #grid>div:nth-child(6n+3){-webkit-perspective-origin: 100% 100%;-moz-perspective-origin: 100% 100%;}
        #grid>div:nth-child(6n+4){-webkit-perspective-origin: 0% 100%;-moz-perspective-origin: 0% 100%;}
        #grid>div:nth-child(6n+5){-webkit-perspective-origin: -100% 100%;-moz-perspective-origin: -100% 100%;}
        #grid>div:nth-child(6n+6){-webkit-perspective-origin: -200% 100%;-moz-perspective-origin: -200% 100%;}

HTML:

<div id="grid">
<div><div>hee</div></div>
<div><div>wat</div></div>
<div><div>is</div></div>
<div><div>dit</div></div>
<div><div>hee</div></div>
<div><div>wat</div></div>
<div><div>is</div></div>
<div><div>dit</div></div>
<div><div>hee</div></div>
<div><div>wat</div></div>
<div><div>is</div></div>
<div><div>dit</div></div>
<div><div>hee</div></div>
<div><div>wat</div></div>
<div><div>is</div></div>
<div><div>dit</div></div>
<div><div>hee</div></div>
<div><div>wat</div></div>
<div><div>is</div></div>
<div><div>dit</div></div>
<div><div>hee</div></div>
<div><div>wat</div></div>
<div><div>is</div></div>
<div><div>dit</div></div>
</div>  
Problem courtesy of: Hacktisch

Solution

About your problems:

  1. The perspective seems to be wrong. Yes, because it is. you need to specify "preserve-3d". If not, the grand-child is rendered over the child, and this one over the base element. The bad news is that property doesn't work in I.E.; so that if you set it will fix it in most browser except I.E.; Also, since I.E. is using the unprefixed syntax, that would make your code not future proof. Just for the demonstrative purposes, it would be that:

    #grid{
        margin:auto;
        width:840px;
        -webkit-transform: rotate3d(1,0,0, 70deg);
        -webkit-transform-style: preserve-3d; 
        margin-top:200px;
    }
    #grid>div{
        -webkit-perspective: 600;
        -moz-perspective: 600;
        perspective: 600;
        -webkit-transform-style: preserve-3d;
        color:white;
        font-family:Arial;
        font-size:70px;
        line-height:140px;
        height:140px;
        width:140px;
        float:left;
        text-align:center;
        cursor:pointer;
        position:relative;
    }
    

(You will see that now the div grows excesively; I leave it as demo purposes)

  1. The perspective changes in smaller sizes. That's because you don't st the perspective origin in the body. if you set

    body { -webkit-perspective: 1000; -webkit-perspective-origin: 420px 0px;
    background: black; -webkit-background-size: cover; -moz-background-size: cover; -o-background-size: cover; background-size: cover; }

That will fix it

About the animation behaving odd; I haven't been unable to reproduce it.

Updated demo

Solution courtesy of: vals

Discussion

There is currently no discussion for this recipe.

This recipe can be found in it's original form on Stack Over Flow.