3D CSS Menu

Another Webkit demo on 3D transforms. This one only fully works in Safari. Chrome is trying, but still a few versions off. This demo also gratuitously includes the :target selector, transitions (from Ceaser of course), and Google webfonts. Plus a :target gotcha that people were hiding from me.

After trying to make the arrow with :after, I learned that you can’t transition pseudo elements. Disappointing, yes, but my big discovery was that from the :target demos I’ve seen, no one mentions that the page will scroll to the named element! Just like a named anchor. Of course it does that. Very annoying. Why is this a secret?

My quick fix was creating a function that gets the current scroll position and then resets it back to that so the page never jumps. Seems functional, but only tested in Safari since the demo is limited to that. (Sorry I don’t have fancy syntax highlighting.)

function noScroll(event) {

    event.preventDefault()

    // store current page scroll
    var x = window.scrollX,
        y = window.scrollY,
    // get the index of the hash
        hashIdx = this.href.indexOf( '#' );

    // set the url hash to everything after the hash so you don't get the full url
    window.location.hash = this.href.substr( hashIdx );

    // scroll back to the original
    window.scrollTo( x, y );

}

var links = document.getElementById('demoNav').getElementsByTagName('a')

for (var i=0; i < links.length; i++) {
    links[i].addEventListener('click', noScroll, false);
}

Anyone else have other fixes for that?

Also...the markup required is a little ugly:

<li>
    <a href="#item1" class="flip" id="item1">
        <div class="front">text</div>
        <div class="top">text<span></span></div>
        <div class="back"></div>
        <div class="bottom"></div>
    </a>
</li>

So a little jQuery goodness could easily be used to convert any list of links into the needed divs:

$('nav li > a').each(function() {

    var text = this.innerHTML;

    $(this).addClass('flip')
           .html( '<div class="front">' + text + '</div><div class="top">' + text + '<span></span></div><div class="back"></div><div class="bottom"></div>' );

});