简体   繁体   中英

Off-Canvas Menu CSS Transition Issue

I'm trying to create an off-canvas menu system that works on both the right and left sides.

I can get the menu's to display correctly and the left menu works exactly how I want it to; however the right hand menu does not close correctly; it jumps before doing the CSS transition. Demo available: http://scottpringle.co.uk/projects/offcanvas/demo/

JSFiddle available: http://jsfiddle.net/D7ZZA/

The code is below:

CSS:

   @import url(http://fonts.googleapis.com/css?family=Lato:400,700,900,400italic,700italic,900italic);
@import url(http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600,700,900,400italic,600italic,700italic,900italic);

/* TODO: Use Flexbox */

/*Set Box Sizing Properties + base font and size */
html {
    box-sizing: border-box;
    font-family: 'Source Sans Pro', sans-serif;
    font-size: 16px;
}

html, body {
    height: 100%;
    margin: 0;
}

p { margin: 0; line-height: 100%; }

ul, li {
    margin: 0;
    list-style: none;
    padding: 0;
}

.fullWidth { width: 100%; }

*, *:before, *:after {
    box-sizing: inherit;
}

img { max-width: 100%; }

/* Set all headers to Lato */
h1, h2, h3, h4, h5, h6 {
    font-family: 'Lato', Arial, Helvetica, sans-serif;
}

.mt-20 { margin-top: 20px; }
.mt-10 { margin-top: 10px; }
.mt-5 { margin-top: 5px; }

.ml-20 { margin-left: 20px; }
.ml-10 { margin-left: 10px; }
.ml-5 { margin-left: 5px; }


.mr-20 { margin-right: 20px; }
.mr-10 { margin-right: 10px; }
.mr-5 { margin-right: 5px; }

.mb-20 { margin-bottom: 20px; }
.mb-10 { margin-bottom: 10px; }
.mb-5 { margin-bottom: 5px; }

.pt-10 { padding-top: 10px; }
.pt-20 { padding-top: 20px; }
.pt-5 { padding-top: 5px; }

.pl-10 { padding-left: 10px; }
.pl-20 { padding-left: 20px; }
.pl-5 { padding-left: 5px; }

.pr-10 { padding-right: 10px; }
.pr-20 { padding-right: 20px; }
.pr-5 { padding-right: 5px; }

.pb-10 { padding-bottom: 10px; }
.pb-20 { padding-bottom: 20px; }
.pb-5 { padding-bottom: 5px;}

.clearfix { clear: both; }

.mainContainer {
    width: 90%;
    margin: 0 auto;
    max-width: 1600px;
}

.logo h1 { margin: 0; }

.contentArea {
    min-height: calc(100% - 6em - 20px);
}

label {
    font-weight: 700;
    text-transform: uppercase;
    padding: 5px 0 2px;
    display: block;
}

input[type="submit"], input[type="button"] {
    border: 1px solid green;
    border-radius: 5px;
    background: green;
    color: white;
    box-shadow: 2px 2px 2px green;
}

header {
    width:100%;
    background: green;
    height: 4em;
    line-height: 4em;
    color: white;
}

footer {
    background: lightgreen;
    width: 100%;
    color: white;
}

footer {
    height: 2em;
    line-height: 2em;
}

header .mainContainer, footer .mainContainer { text-align: center; }

.left { float: left; }
.right { float: right; }

.leftContent, .rightContent {
    width: 200px;
}

.alignLeft { text-align: left !important; }
.alignRight { text-align: right !important; }
.alignCentre { text-align: center !important; }


.sectionTitle {
    height: 2em;
    font-size: 2em;
    /*margin: 0.67em 0;*/
    background-color: green;
    opacity: 0.7;
    line-height: 2em;
    text-align: center;
    color: white;
}

.centreContent {
    margin: 0 50px;
    width: calc(100% - 500px);
}

.sectionArea {
    border: 1px solid green;
}

.sectionArea .sectionContent {
    padding: 10px 10px 5px;
}

.noPadding { padding: 0 !important; }

.relative { position: relative; }

nav.leftSide > ul > li > ul > li.childNav > ul > li {
    font-size: 0.8rem;
    padding-left: 15px;
}

.off-canvas {
    width: 10rem;
    height: 100%;
    background-color: #eeeeee;
    position: fixed;
    top: 0;
    -webkit-transition: left 2s, right 2s; /* For Safari 3.1 to 6.0 */
    transition: left 2s, right 2s;
}

.off-canvas.nav-right {
    right: -10rem;
}

.off-canvas.nav-left {
    left: -10rem;
}

.off-canvas.nav-left.open {
    left: 0;
}

.off-canvas.nav-right.open {
    right: 0;
}

.page-wrap {
    -webkit-transition: all 2s;
    transition: all 2s;
    position: relative;
    left: 0;
    right: 0;
}

.page-wrap.wrap-left {
    left: 10rem;
    right: auto;
}

.page-wrap.wrap-right {
    right: 10rem;
    left: auto;
}

nav.off-canvas > ul li {
    border-bottom: 1px solid green;
}

nav.off-canvas > ul li:last-child {
    border-bottom: none;
}

nav.off-canvas > ul li.navTitle {
    padding-left: 10px;
    font-size: 1.5rem;
}
nav.off-canvas > ul li.navChild {
    background: #aaaaaa;
    padding-left: 20px;
    font-size: 1.2rem;
}

nav.off-canvas > ul > li.navMenu > ul > li.slide {
    display: none;
}

.headerMenu.fa {
    line-height: 2.75;
    font-size: 1.5rem;
    cursor: pointer;
}

HTML:

<html>
<head>
    <link href="//cdnjs.cloudflare.com/ajax/libs/normalize/3.0.1/normalize.min.css" type="text/css" rel="stylesheet" />
    <!--TODO: Re-add font-awesome-->
    <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet">

    <!--TODO: Convert to absolute URL format-->
    <link href="css/style.css" rel="stylesheet" type="text/css" />

    <title>ScorePredcitor</title>
</head>
<body>

<nav class="nav-left off-canvas">
    <p>Left Menu</p>
</nav>

<nav class="nav-right off-canvas">
    <p>Right Menu</p>
</nav>

<div class="page-wrap">

    <header class="clearfix">
        <section class="visible-mobile visible-tablet left headerMenu fa fa-bars" data-menu="nav-left">
        </section>
        <section class="mainContainer left">
            <!--Site Header-->
            <article class="logo">
                <h1>Off Canvas</h1>
            </article>
        </section>
        <section class="visible-mobile right headerMenu fa fa-bars" data-menu="nav-right">
        </section>
    </header>
    <div class="mainContainer contentArea">
        <article class="centreContent left">
            <p>Click bars at the top to view menus</p>
        </article>
        <div class="clearfix"></div>
    </div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script type="text/javascript" src="../assets/javascript/main.js"></script>
</body>
</html>

Javascript:

$(document).ready(function(){
    $(document).on('click tap', '.headerMenu', function(e){
        e.preventDefault();
        e.stopImmediatePropagation();

        //Get menu
        var toOpen = $(this).data('menu');
        var menu = $('.'+toOpen);
        var openClose = (menu.hasClass('open')) ? true : false;
        menu.toggleClass('open');

        var navSides = toOpen.split('-');
        var side = navSides[1];
        $(".page-wrap").removeClass('wrap-left wrap-right');
        if(openClose == false) {
            $(".page-wrap").addClass('wrap-'+side);
        }
    });

    $(document).on('click tap', 'nav.off-canvas > ul > li.navMenu > ul > li.navTitle', function(e){
        e.preventDefault();
        e.stopImmediatePropagation();
        if ($(this).siblings('li.slide')) {
            $(this).siblings('li.slide').slideToggle('fast');
        }

        ($(this).children('i').hasClass('fa-arrow-circle-down')) ? $(this).children('i').removeClass('fa-arrow-circle-down').addClass('fa-arrow-circle-up') : $(this).children('i').removeClass('fa-arrow-circle-up').addClass('fa-arrow-circle-down');
    })
});

From what I am seeing it looks like CSS does not like to transition left:auto to left: 0. I believe the reason why is by default left is 0. When the right measurement of 10rem is replaced by 0rem it looks like the left is not really listening and thinks auto was 0 to start with which is why it jumps. I would suggest just moving the left with the right at once. Because you are using a static measurement accuracy is assured. See modified class below.

You are transitioning everything so this should slide in fine as you can see here http://jsfiddle.net/D7ZZA/1/

.page-wrap.wrap-right {
  right: 10rem;
  left: -10rem;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM