2

Off-Canvas 滑动导航现在逐渐在移动页面变得越来越流行了,本文就将讨论如何通过 jQuery 增添、删除类来操作 CSS 过渡和动画完成这样的效果。

本教程将用到的资源:

clipboard.png

Demo / Download

开始

引入相关的库,如:

<!-- Styles -->
    <link href="css/reset.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">

<!-- Fonts -->
    <link href=
    'http://fonts.googleapis.com/css?family=Raleway:400,600,500,700,800' rel=
 'stylesheet' type='text/css'>
    <link href=
    'http://fonts.googleapis.com/css?family=Lato:400,700,900,300italic,400italic'
    rel='stylesheet' type='text/css'>
    <link href=
    "http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css"
    rel="stylesheet">

<!-- Scripts -->
    <script src="js/jquery.min.js"></script>
    <script src="js/custom.js"></script>

HTML

Off-Canvas 滑动导航和传统的导航不同的地方在于:

  • Container 容器——包裹 body 里的所有标签、控制元素的显示/隐藏
  • Canvas 画布——用于滑动效果制作的 div
  • Navigation 导航——包裹滑动导航的 div

基本结构:

<div id="container">
    <div id="canvas">
        <div id="nav">
        //Sliding Navigation Content Here

        </div>
    </div>
</div>

加入主要元素:

<div id="container">
        <div id="canvas">
            <div id="nav">
                <h2 id="title"><i class="fa fa-sitemap"></i> MENU</h2>
                <ul id="toggle">
                    <li>
                        <div class="active border">
                            <span class="menu-icons fa fa-home"></span>   <a href="#">HOME</a>
                        </div>
                    </li>
                    <li>
                        <div>
                            <span class="menu-icons  fa fa-user"></span>   <a href="#">ABOUT US</a>
                            <span class="the-btn fa fa-plus"></span>
                            </div>
                        <ul>
                            <li>
                                <a href="#">OUR TEAM</a>
                            </li>
                            <li>
                                <a href="#">OUR SERVICES</a>
                            </li>
                        </ul>
                    </li>
                    <li>
                        <div>
                            <span class="menu-icons  fa fa-briefcase"></span>
                                <a href="#">PORTFOLIO</a><span class="the-btn fa fa-plus"></span>
                        </div>
                        <ul>
                            <li>
                                <a href="#">WEB DESIGN</a>
                            </li>

                            <li>
                                <a href="#">GRAPHIC DESIGN</a>
                            </li>
                        </ul>
                    </li>
                    <li>
                        <div>
                            <span class="menu-icons  fa fa-envelope"></span>
                                  <a href="#">CONTACT</a>
                        </div>
                    </li>
                </ul>
             </div>
            <a href="#" class="toggle-nav" id="bars"><i class="fa fa-bars"></i></a>
            <h1>Off Canvas Sliding Navigation</h1>
            <h3>Transition effect for off-canvas views with sliding navigation </h3>
            <p> <a href="#" class="back">← Back to the Article</a></p>
       </div>
    </div>

要说明的几点:

  • 含有 toggle id 的无序列表待会儿将被用于滑动特效
  • 带有 font-awesome 图标的列表链接到每个独立的菜单。
  • 如果有子菜单,加上 (+) 按钮图标,点击后通过 jQuery 来切换成 (-)。
  • 包含 .toggle-nav#bars 的三条线的图标用于切换导航的显示隐藏

HTML建好了,接下来开始做酷炫的事情~

CSS

基本样式:

html,
body{
background: #f3efe0;
}

h1, h2, h3{
    text-align: center;
}

h1{
    font-family: 'Raleway', Arial, sans-serif;
    font-weight: 700;
    font-size: 45px;
    margin-top: 15px;
    color: #38935f;
}

h3{
    font-family: 'Raleway', Arial, sans-serif;
    font-weight: 400;
    font-size: 25px;
    margin-top: 15px;
    color: #918e84;
}

container 把 canvas 和 navigation 包裹起来

#container {
    width: 100%;
    height: 100vh;
    position: relative;
    overflow: hidden;
}

注意:这里使用 vh (viewport’s height) 作高度单位,100% 的高度可以自适应屏幕高度。

现在来看看到 canvas 元素。设置为相对定位和 100% 的高度,加一下过渡属性:

#canvas {
    width: 100%;
    height: 100%;
    padding: 5.5% 0;
    position: relative;

    -webkit-transform:translateX(0);
    -moz-transform:translateX(0);
    -ms-transform:translateX(0);
     -o-transform:translateX(0);
        transform:translateX(0);

    -webkit-transition:.5s ease all;
    -moz-transition:.5s ease all;
     -o-transition:.5s ease all;
        transition:.5s ease all;
}

给 nav 元素加上绝对定位和一些过渡。

#nav {
    width: 300px;
    height: 100%;
    background: #38935f;
    position: absolute;
    left: -300px;
    top: 0;

    -webkit-transition:.5s ease all;
    -moz-transition:.5s ease all;
     -o-transition:.5s ease all;
        transition:.5s ease all;

/* By default, rotate the menu 90deg inwards */
    -webkit-transform:rotateY(-90deg);
    -moz-transform:rotateY(-90deg);
    -ms-transform:rotateY(-90deg);
     -o-transform:rotateY(-90deg);
        transform:rotateY(-90deg);
}

补充一些美化的样式:

#bars{
    font-size: 34px;
    margin-left: 49px;
    color: #38935f;
}
#bars:hover{
    color: #48b978
}
#title{
    margin: 0;
    padding: 1em;
    color: rgba(0,0,0,0.4);
    text-shadow: 0 0 1px rgba(0,0,0,0.1);
    font-weight: 300;
    font-size: 2em;
    font-family: 'Raleway', Arial;
}
.border{
    border-top: 1px solid rgba(0,0,0,0.2);
}
a.back {
    color: #38935f;
    width: 200px;
    text-decoration: none;
    text-align: center;
    font-family: 'Raleway';
    font-size: 20px;
    font-weight: 600;
    display: block;
    margin: 50px auto 0 auto;
    border: 2px solid #38935f;
    padding: 10px;
}
a.back:hover{
    color: #48b978;
    border: 2px solid #48b978;
}

.clear {
    clear: both;
    display: block;
    overflow: hidden;
    visibility: hidden;
}

还要给滑动的导航美化一下,包括菜单显示、隐藏时的样式、背景色、菜单图标等。

待会儿会用 jQuery 来进行操作酷炫的滑动动画。

#toggle {
    list-style: none;
    margin-top: 40px;
}
#toggle div:hover {
    background: rgba(0,0,0,0.2);
    -webkit-box-shadow:inset 0 -1px rgba(0,0,0,0);
    -moz-box-shadow:inset 0 -1px rgba(0,0,0,0);
    box-shadow:inset 0 -1px rgba(0,0,0,0);
    color: #fff;
}
#toggle div.active {
    background: #1f9d55;
}
#toggle div {
    cursor: pointer;
    display: block;
    border-bottom: 1px solid rgba(0,0,0,0.2);
}
 span.menu-icons {
    font-size: 20px;
    height: 20px;
    width: 22px;
    float: left;
    margin: 11px 0px 10px 37px;
    color: #fff;
}
span.the-btn {
    float: right;
    font-size: 20px;
    height: 30px;
    width: 43px;
    margin-top: 10px;
    margin-right: 8px;
    padding:0;
    color: #fff;
}
#toggle ul {
    list-style: disc;
    display: none;
    color: #fff;
    background: rgba(0,0,0,0.2);
    -webkit-box-shadow:inset 0 -1px rgba(0,0,0,0);
    -moz-box-shadow:inset 0 -1px rgba(0,0,0,0);
    box-shadow:inset 0 -1px rgba(0,0,0,0);
}
#toggle li a {
    line-height: 41px;
    color: #fff;
    list-style: circle;
    width: 240px;
    padding: 0;
    margin: 0 0 0 50px;
}
#toggle a {
    margin: 0 0 0 47px;
    padding: 0;
    font-family: 'Lato';
    color: #fff;
    line-height: 41px;
    font-weight: normal;
    font-size: 18px;
    text-decoration: none;
}
#toggle ul li {
    margin-left: 109px;
}
#toggle ul li a:hover{
    background: #1f9d55;
}
#toggle ul li a {
     margin-left: 0;
}

最后进行动画样式设置:将用到 transform 属性和从左到右 3D 旋转变换。

#nav {
    width: 300px;
    height: 100%;
    background: #38935f;
    position: absolute;
    left: -300px;
    top: 0;

    -webkit-transition:.5s ease all;
    -moz-transition:.5s ease all;
    -o-transition:.5s ease all;
    transition:.5s ease all;

/* By default, rotate the menu 90deg inwards */
    -webkit-transform:rotateY(-90deg);
    -moz-transform:rotateY(-90deg);
    -ms-transform:rotateY(-90deg);
     -o-transform:rotateY(-90deg);
        transform:rotateY(-90deg);
}

#container.display-nav #canvas {
   -webkit-transform:translateX(300px);
   -moz-transform:translateX(300px);
    -ms-transform:translateX(300px);
     -o-transform:translateX(300px);
        transform:translateX(300px);
}

/* transition the menu with perspective on "show-nav" */
#container.display-nav #nav {
   -webkit-transform-origin:100% 50%;
   -moz-transform-origin:100% 50%;
    -ms-transform-origin:100% 50%;
     -o-transform-origin:100% 50%;
        transform-origin:100% 50%;

   -webkit-transform:perspective(600px) rotateY(0deg);
   -moz-transform:perspective(600px) rotateY(0deg);
    -ms-transform:perspective(600px) rotateY(0deg);
     -o-transform:perspective(600px) rotateY(0deg);
        transform:perspective(600px) rotateY(0deg);
}

jQuery

首先通过 .toggle-nav 元素切换效果,给元素增删 display-nav 类来完成效果。

// 调用toggleNavigation
$(function() {
    $('.toggle-nav').click(function() {
        toggleNavigation();
    });
});

// toggleNavigation 方法
function toggleNavigation() {
    if ($('#container').hasClass('display-nav')) {
        // 关闭 Nav
        $('#container').removeClass('display-nav');
    } else {
        // 打开 Nav
        $('#container').addClass('display-nav');
    }
}

现在,整个块元素能正确地显示,已经有了 off-page canvas,也完成了 jQuery 滑动效果。如下这段代码,利用 $currIcon=$(this).find(“span.the-btn”) 创建一个变量来传递当前菜单图标,然后把所有的图标做成折叠状态(用加号图标),用 toggle 类把加/减图标存储在 $curricon 里。

$("#toggle > li > div").click(function () {
    if (false == $(this).next().is(':visible')) {
        $('#toggle ul').slideUp();
    }

    var $currIcon=$(this).find("span.the-btn");

    $("span.the-btn").not($currIcon).addClass('fa-plus').removeClass('fa-minus');

    $currIcon.toggleClass('fa-minus fa-plus');

    $(this).next().slideToggle();

    $("#toggle > li > div").removeClass("active");
    $(this).addClass('active');

});

结语

Demo / Download

现在已经成功地完成了一个很棒的 off-canvas 导航菜单。希望这篇文章对读者能有启发,如果你还感兴趣,那就一块来动手实现一个吧。


原文 How to Create Off-Canvas Sliding Navigation Menu
编译 SegmentFault


江小湖Laker
6.9k 声望371 粉丝

进击的程序媛快去创造奇迹~