Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I prevent a responsive nav menu (powered by a CSS3 transition) from animating when different media queries take effect?

Preface

I'm trying to create a responsive website with a navigation menu that satisfies the following two requirements:

  1. Navigation is fully visible in a normal browser window, laid out horizontally.
  2. Navigation becomes a toggleable vertical menu for mobile devices and small screens, which animates between its "opened" and "closed" state.

I want performance to be good on mobile devices — especially on iOS — which means that the animation should use a GPU-accelerated translate3d transform CSS transition.

My Problem

Setting this up was a piece of cake, and for the most part it works great. I used z-index: 1 and transform: translate3d(0,-100%,0) to hide the menu behind a header with z-index: 2 in its default closed state, and then transform: translate3d(0,0,0) to animate the menu to its opened state.

But I'm just having one problem: When I resize my Chrome browser window and the mobile media query kicks in, the menu animates from an opened to closed state.

Resize your browser window to less than 600px wide to see the problem in action:

  • Fullscreen jsfiddle: http://fiddle.jshell.net/ymDYG/1/show/
  • Original jsfiddle: http://jsfiddle.net/ymDYG/1/

I think I know why this is happening: when the mobile media query kicks in, the browser sees that .nav is not currently active, so it animates it to the default closed state. I've tried experimenting with using display:none and display:block for the different media query states, but that seems to completely break the animation.

How can I prevent the nav menu's "closing" animation from firing as the browser window is resized?

like image 813
Michael Avatar asked May 20 '13 16:05

Michael


1 Answers

Nice job, very clean. Can i steal it? :-)

Anyway, here's your solution with a demo.

I just moved the transition to another class:

.nav {
    /* stuff */
    z-index: 1;
    transform: translate3d(0,-100%,0);
    -webkit-transform: translate3d(0,-100%,0);
}
.nav.active {
    transform: translate3d(0,0,0);
    -webkit-transform: translate3d(0,0,0);
}
.nav.activated {
    transition: transform 400ms linear;
    -webkit-transition: -webkit-transform 400ms linear;
}

Which you can add to the element at first "Toggle":

function toggle(){
    $(".nav").addClass("activated").toggleClass("active");
}

P.S. If you don't want the transition to happen even after the user has opened the menu and then resized the window again, you could use Modernizr's mq method:

$(window).on('resize',function(){
    if(Modernizr.mq('(min-width:600px)')) $(".nav").removeClass("activated");
});
like image 79
Giona Avatar answered Oct 17 '22 17:10

Giona