0

I have an off canvas menu demo here:

jsfiddle

The toggle button itself works as expected (menu slides in and out) but the problem is that when the menu is 'off', if you resize the browser from wide to narrow, you'll see the menu animate.

The JS just toggles a class on the HTML element. CSS transitions and transforms do the moving and animation of the menu. It's because that menu has a transition on it so it's animating moving it off the screen for the smaller screen size. I want the transition when you click the toggle button, but I don't want it just when the browser is resized.

Note that I don't want to use JS for the animation.

HTML:

<header class="Header" role="banner">
    <div class="GlobalLogo"></div>
    <button class="GlobalNavToggle js-globalNavToggle" type="button">Toggle navigation</button>
    <nav class="GlobalNav">
        <!--<h2 class="u-srOnly">Main Menu</h2>-->
        <ul class="GlobalNav_list">
            <li class="GlobalNav_item">
                <a class="GlobalNav_link" href="#">Top level 1</a>
            </li>
            <li class="GlobalNav_item">
                <a class="GlobalNav_link" href="#">Top level 2</a>
            </li>
            <li class="GlobalNav_item">
                <a class="GlobalNav_link" href="#">Top level 3</a>
            </li>
            <li class="GlobalNav_item">
                <a class="GlobalNav_link" href="#">Top level 4</a>
            </li>
            <li class="GlobalNav_item">
                <a class="GlobalNav_link" href="#">Top level 5</a>
            </li>
        </ul>
    </nav>
</header>
<div class="Main clearfix" role="Main">
    <p>...</p>
</div>

SCSS:

body {
    margin: 0;
    .isActiveGlobalNav & {
        overflow: hidden;
    }
}

.clearfix:before,
.clearfix:after {
    content: " "; /* 1 */
    display: table; /* 2 */
}

.clearfix:after {
    clear: both;
}

.Container {
    max-width: 900px;
}

.Main {
    clear: both;
    margin-top: 30px;
}

.GlobalLogo {
    float: left;
    margin-right: 20px;
    background-size: 100%;
    background-image: url('http://placehold.it/100x35');
    background-repeat: no-repeat;
    width: 100px;
    height: 35px;
}

.GlobalNav {
    clear: both;
    @media only screen and (max-width : 600px) {
        width: 70%;
        transform: translate3d(-100%, 0, 0);
        position: absolute;
        background: rgba(0,0,0,.9);
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        transition: transform .25s ease-in;

        .isActiveGlobalNav & {
            transform: translate3d(0, 0, 0);
        }
    }
    @media only screen and (min-width : 601px) {
        clear: none;
        float: left;
    }
}
.GlobalNav_list {
    list-style: none;
    padding: 0;
    margin: 0;
}
.GlobalNav_item {
    @media only screen and (min-width : 601px) {
        float: left;
    }
}
.GlobalNav_link {
    padding: 10px;
    display: block;
    color: white;
    text-decoration: none;
    @media only screen and (min-width : 601px) {
        color: black;
    }
}

.GlobalNavToggle {
    float: right;
    margin-top: 7px;
    line-height: 20px;
    background: yellow;
    border: none;
    cursor: pointer;
    @media only screen and (min-width : 601px) {
        display: none;
    }
}

JS

var navigation = function () {

    var $html = $('html'),
        //$globalNav = $('GlobalNav'),
        $globalNavToggle = $('.js-globalNavToggle');

    $globalNavToggle.on('touchstart click', function () {

        $html.toggleClass('isActiveGlobalNav');

    });

};

navigation();
urbz
  • 2,663
  • 1
  • 19
  • 29
davidpauljunior
  • 8,238
  • 6
  • 30
  • 54

1 Answers1

2

I can suggest to move transition to a separate class, than remove that class on resizing and turn it back when resize is stopped:

$(window).on('resize', function(){
  clearTimeout(timeout);
  $globalNav.removeClass('animated');
  timeout = setTimeout(function(){
      $globalNav.addClass('animated');
  }, 100);
});

(original idea from here)

and jsFiddle

Community
  • 1
  • 1
Roman Bekkiev
  • 3,010
  • 1
  • 24
  • 31