简体   繁体   中英

Off-canvas navigation: How to make a second-level menu slide in on top of first-level menu without covering body text?

I've been tasked to make a two-level off-canvas navigation menu that has main nav menu. Each "level 1" nav item has a sub-nav flyout with contents in it. While I have most of this worked out, I'm frustrated by one requirement. That requirement is to be able to make the sub nav flyout "slide in" from the right.

Here is my code in JS Fiddle: http://jsfiddle.net/tangst/cca42qd6/
or run the embedded snippet after the code.

Note: Your browser viewport must be less than 979px, because this menu is only seen at smaller viewports.

 $(document).ready(function () { $(".masthead-nav-burgericon").on("click", function (event) { $(".masthead-nav-burgericon").toggleClass("open"); $("body").toggleClass("is-offcanvas"); $(".masthead-nav-list").addClass("is-visible"); event.preventDefault(); }); $(".masthead-channel-link").on("click", function (event) { var $mastheadFlyout = $(this).parent(".masthead-nav-channel").children(".masthead-flyout"), $mastheadNav = $(".masthead-nav-list"); if ($mastheadFlyout.hasClass("is-visible")) { $mastheadFlyout.removeClass("is-visible"); $mastheadNav.removeClass("is-covered"); } else { $mastheadFlyout.addClass("is-visible"); $mastheadNav.addClass("is-covered"); } event.preventDefault(); }); }); 
 /* Micro clearfix */ .cf:before, .cf:after { content:" "; display: table; } .cf:after { clear: both; } .masthead-wrapper { position: relative; } .masthead-wrapper * { box-sizing: border-box; } #masthead .masthead-wrapper ul, .masthead-wrapper ul { list-style-type: none; margin: 0; padding: 0; } @media only screen and (max-width: 979px) { /* BEGIN - Off-canvas styles */ body { left: 0; -webkit-transform: translateX(0); -moz-transform: translateX(0); -ms-transform: translateX(0); transform: translateX(0); -webkit-transition: -webkit-transform 500ms ease; -moz-transition: -moz-transform 500ms ease; transition: transform 500ms ease; } body.is-offcanvas { left: 0; overflow-x: hidden; -webkit-transform: translateX(70%); -moz-transform: translateX(70%); -ms-transform: translateX(70%); transform: translateX(70%); -webkit-transition: -webkit-transform 500ms ease; -moz-transition: -moz-transform 500ms ease; transition: transform 500ms ease; } .masthead-nav-list { border: 1px solid #ccc; position: absolute; left: -9999px; } .masthead-nav-list.is-visible { height: 500px; left: -250px; top: 0; width: 250px; } .masthead-nav-list.is-covered { } /* END - Off-canvas styles */ .masthead-flyout { border: 1px solid #f00; background-color: #ffffff; height: 1000px; left: 100%; position: absolute; top: 0; -webkit-transform: translateX(0); -moz-transform: translateX(0); -ms-transform: translateX(0); transform: translateX(0); -webkit-transition: -webkit-transform 500ms ease; -moz-transition: -moz-transform 500ms ease; transition: transform 500ms ease; width: 200px; } .masthead-flyout.is-visible { overflow-x: hidden; overflow-y: auto; -webkit-transform: translateX(-100%); -moz-transform: translateX(-100%); -ms-transform: translateX(-100%); transform: translateX(-100%); -webkit-transition: -webkit-transform 500ms ease; -moz-transition: -moz-transform 500ms ease; transition: transform 500ms ease; } /* This does not flex because it's a small, fixed icon */ .masthead-nav-burgericon-wrapper { width: 50px; } .masthead-nav-burgericon { width: 50px; height: 30px; position: relative; -webkit-transform: rotate(0deg); -moz-transform: rotate(0deg); transform: rotate(0deg); -webkit-transition: .5s ease-in-out; -moz-transition: .5s ease-in-out; transition: .5s ease-in-out; cursor: pointer; } .masthead-nav-burgericon span { background: #000000; border-radius: 2px; height: 5px; left: 5px; opacity: 1; position: absolute; -webkit-transform: rotate(0deg); -moz-transform: rotate(0deg); transform: rotate(0deg); -webkit-transition: .25s ease-in-out; -moz-transition: .25s ease-in-out; transition: .25s ease-in-out; width: 25px; } .masthead-nav-burgericon span:nth-child(1) { top: 2px; } .masthead-nav-burgericon span:nth-child(2) { top: 12px; } .masthead-nav-burgericon span:nth-child(3) { top: 22px; } .masthead-nav-mobile-sitelogo-wrapper .masthead-nav-burgericon span:nth-child(1) { top: 12px; -webkit-transform: rotate(135deg); -moz-transform: rotate(135deg); -o-transform: rotate(135deg); transform: rotate(135deg); } .masthead-nav-mobile-sitelogo-wrapper .masthead-nav-burgericon span:nth-child(2) { top: 12px; -webkit-transform: rotate(-135deg); -moz-transform: rotate(-135deg); -o-transform: rotate(-135deg); transform: rotate(-135deg); } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script> <body> <div> <header id="masthead" class="masthead-wrapper"> <nav class="masthead-nav"> <div class="masthead-nav-burgericon-wrapper"> <div class="masthead-nav-burgericon"> <span></span> <span></span> <span></span> </div> </div> <ul class="masthead-nav-list"> <li class="masthead-nav-mobile-sitelogo-wrapper"> <div class="masthead-nav-closeicon"> <div class="masthead-nav-burgericon"> <span></span> <span></span> </div> </div> </li> <li class="masthead-nav-channel masthead-channel-az"> <a href="#" class="masthead-channel-link">Level 1 Nav</a> <div class="masthead-flyout masthead-flyout-nav"> <div class="masthead-flyout-col"> <div class="masthead-conditions-wrapper cf"> <div class="masthead-conditions-header-wrapper cf">Level 1 Sub-Nav (Contents): This should be hidden until you click the "Nav" link. This sub-nav should not be covering the main content (Lorem Ipsum) below.</div> </div> </div> </div> </li> </ul> </nav> </header> </div> <div> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p> </div> </body> 

Click on the "hamburger" icon and the "Lorem Ipsum" body text will shift to the right (this is the desired behavior). Then, you will see the "Level 1 Nav" with a gray border. In addition, you will see the "Level 1 Sub-Nav" div with a red border. That "Level 1 Sub-Nav" flyout is covering the "lorem ipsum" body text. That is NOT correct behavior. This "Level 1 Sub-Nav" flyout should not be covering up the body text at all. It should be invisible.

When you click on the "Level 1 Nav" link, you will see that the sub-nav flyout slides over to the left using using the CSS transform translateX() property. In the correct situation, the sub-nav slides in from the body text's left edge boundary; the sub-nav doesn't cover up the body text to begin with.

The only way I have been able to make this work is by applying display: none on the .masthead-flyout class, and then applying display: block to it when the user clicks on the "Level 1 Sub-Nav" link, but this negates the translateX() animation.

So, how do I keep the sub-nav from covering up the body text AND create the sub-nav slide-in effect?

the .masthead-flyout is being rendered outside its parent's bounds, you could add overflow:hidden to the parent. I think that would be the most minimal change to achieve the effect.

    .masthead-nav-list {
        border: 1px solid #ccc;
        position: absolute;
        left: -9999px;
        overflow:hidden;/*add this*/
    }

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