这是一款基于bootstrap4的滑动侧边栏特效。该滑动侧边栏使用bootstrap4框架,通过css和jquery来完成隐藏侧边栏,当点击打开侧边栏按钮时,侧边栏会以动画的方式滑动出来。
使用方法
在页面中引入jquery和bootstrap4相关文件。
<link href="css/bootstrap.min.css" rel="stylesheet"> <script src="js/jquery-1.11.0.min.js" type="text/javascript"></script> <script src="js/bootstrap.min.js"></script>
HTML结构
侧边栏的HTML结构如下:
<nav class="navbar navbar-expand-md navbar-dark bg-dark navbar-offcanvas"> <div class="container-fluid"> <a class="navbar-brand" href="#">Navbar</a> <ul class="navbar-nav navbar-top"> <li class="nav-item active"> <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> </ul> <button class="navbar-toggler navbar-toggler-right navbar-icon" type="button" data-toggle="collapse" data-target="#navbar-mobile" aria-controls="navbar-mobile" aria-expanded="false" aria-label="Toggle navigation"> <span class="icon-bar bar1"></span> <span class="icon-bar bar2"></span> <span class="icon-bar bar3"></span> </button> <div class="navbar-collapse collapse ml-auto" id="navbar-mobile"> <ul class="navbar-nav ml-auto"> <li class="nav-image"> <img src="logo.png" alt=""> </li> <li class="nav-item"> <a href="#!" class="nav-link">Link 1</a> </li> <li class="nav-item"> <a href="#!" class="nav-link">Link 2</a> </li> <li class="nav-item"> <a href="#!" class="nav-link">Link 3</a> </li> </ul> </div> </div> </nav>
页面的内容放置在wrapper
class的div容器中。
<div class="wrapper"> ... </div>
CSS样式
为侧边栏添加下面的CSS样式。
.wrapper { transition: all 0.5s cubic-bezier(0.685, 0.0473, 0.346, 1); } .navbar { height: 75px; transition: all .5s .1s; } .navbar-offcanvas { z-index: 1030; } .navbar-offcanvas .container-fluid { position: relative; padding: 0; transform: translate3d(0px, 0, 0); transition: all 0.5s cubic-bezier(0.685, 0.0473, 0.346, 1); } .navbar-offcanvas .navbar-top { display: none; } @media (min-width: 992px) { .navbar-offcanvas .navbar-top { display: flex; margin-left: auto; } } .navbar-offcanvas .navbar-top .nav-item { margin-right: 22px; text-align: center; } @media (max-width: 991px) { .navbar-offcanvas .navbar-top .nav-item .nav-link { color: #000; } } .navbar-offcanvas .navbar-toggler { padding: 0; border: 0; outline: none; } .navbar-offcanvas .navbar-toggler:hover, .navbar-offcanvas .navbar-toggler:focus { cursor: pointer; } @media (min-width: 768px) { .navbar-offcanvas .navbar-toggler { display: block; } } .navbar-offcanvas .navbar-toggler .icon-bar { display: block; position: relative; width: 24px; height: 2px; border-radius: 1px; background-color: #fff; } .navbar-offcanvas .navbar-toggler .icon-bar + .icon-bar { margin-top: 4px; } .navbar-offcanvas .navbar-toggler .icon-bar.bar1 { top: 0; outline: 1px solid transparent; animation: topbar-back 500ms 0s; animation-fill-mode: forwards; } .navbar-offcanvas .navbar-toggler .icon-bar.bar2 { outline: 1px solid transparent; opacity: 1; } .navbar-offcanvas .navbar-toggler .icon-bar.bar3 { bottom: 0; outline: 1px solid transparent; animation: bottombar-back 500ms 0s; animation-fill-mode: forwards; } .navbar-offcanvas .navbar-toggler.toggled .icon-bar.bar1 { top: 6px; animation: topbar-x 500ms 0s; animation-fill-mode: forwards; } .navbar-offcanvas .navbar-toggler.toggled .icon-bar.bar2 { opacity: 0; } .navbar-offcanvas .navbar-toggler.toggled .icon-bar.bar3 { bottom: 6px; animation: bottombar-x 500ms 0s; animation-fill-mode: forwards; } .navbar-offcanvas .navbar-collapse.collapse, .navbar-offcanvas .navbar-collapse.collapse.in, .navbar-offcanvas .navbar-collapse.collapsing { display: none !important; } .nav-open .navbar-collapse { transform: translate3d(0px, 0, 0); } .nav-open .navbar > .container-fluid { transform: translate3d(-424px, 0, 0); } @media (max-width: 991px) { .nav-open .navbar > .container-fluid { transform: translate3d(-282.6666666667px, 0, 0); } } .nav-open .wrapper { transform: translate3d(-150px, 0, 0); } body > .navbar-collapse { display: block !important; position: fixed; top: 0; right: -10px; width: 424px; height: 100%; padding: 60px 1rem; background-color: #fff; border-left: 1px solid #e3e3e3; text-align: center; visibility: visible; overflow-y: visible; transform: translate3d(424px, 0, 0); transition: all 0.5s cubic-bezier(0.685, 0.0473, 0.346, 1); z-index: 1032; } body > .navbar-collapse:after { content: ""; position: absolute; top: 28px; left: -20px; border-left: 10px solid #fff; border-top: 10px solid transparent; border-bottom: 10px solid transparent; border-right: 10px solid transparent; transform: rotate(180deg); transition: all 0.5s cubic-bezier(0.685, 0.0473, 0.346, 1); z-index: 1032; } @media (max-width: 991px) { body > .navbar-collapse { width: 282.6666666667px; } } body > .navbar-collapse .nav-image { margin-bottom: 65px; } body > .navbar-collapse .nav-image img { display: block; margin: 0 auto; border: 1px solid rgba(0, 0, 0, 0.14); width: 91px; height: 69px; } body > .navbar-collapse .navbar-top { margin: 0 !important; flex-direction: column; } @media (min-width: 992px) { body > .navbar-collapse .navbar-top { display: none; } } body > .navbar-collapse .navbar-top li { text-align: center; } body > .navbar-collapse .navbar-top li a { display: block; padding: .5rem 1rem; font-weight: 700; color: #000; } body > .navbar-collapse .navbar-top li a:hover, body > .navbar-collapse .navbar-top li a:focus { text-decoration: none; } body > .navbar-collapse .nav-link, body > .navbar-collapse .dropdown-toggle { font-weight: 700; color: #222; transition: color .2s ease-out; } body > .navbar-collapse .nav-link:hover, body > .navbar-collapse .nav-link:focus, body > .navbar-collapse .dropdown-toggle:hover, body > .navbar-collapse .dropdown-toggle:focus { text-decoration: none; } body > .navbar-collapse .nav-link.disabled, body > .navbar-collapse .dropdown-toggle.disabled { color: rgba(0, 0, 0, 0.35); } body > .navbar-collapse .nav-link.disabled:hover, body > .navbar-collapse .nav-link.disabled:focus, body > .navbar-collapse .dropdown-toggle.disabled:hover, body > .navbar-collapse .dropdown-toggle.disabled:focus { cursor: not-allowed; } @media (min-width: 992px) { body > .navbar-top { display: none; } } body > #overlay { content: ""; position: fixed; top: 0; left: auto; right: calc(282.6666666667px - 10px); width: 100%; height: 100%; opacity: 0; overflow-x: hidden; z-index: 1029; } @media (min-width: 992px) { body > #overlay { right: calc(424px - 10px); } } @keyframes topbar-x { 0% { top: 0px; transform: rotate(0deg); } 45% { top: 6px; transform: rotate(145deg); } 75% { transform: rotate(130deg); } 100% { transform: rotate(135deg); } } @keyframes topbar-back { 0% { top: 6px; transform: rotate(135deg); } 45% { transform: rotate(-10deg); } 75% { transform: rotate(5deg); } 100% { top: 0px; transform: rotate(0); } } @keyframes bottombar-x { 0% { bottom: 0px; transform: rotate(0deg); } 45% { bottom: 6px; transform: rotate(-145deg); } 75% { transform: rotate(-130deg); } 100% { transform: rotate(-135deg); } } @keyframes bottombar-back { 0% { bottom: 6px; transform: rotate(-135deg); } 45% { transform: rotate(10deg); } 75% { transform: rotate(-5deg); } 100% { bottom: 0px; transform: rotate(0); } }
CSS样式
最后通过下面的js代码来完成侧边栏的显示和隐藏。
var window_height; var window_width; var navbar_initialized = false; var nav_toggle; var offCanvas = { sidenav: { // Sidenav is not visible by default. // Change to 1 if necessary sidenav_visible: 0 }, initSideNav: function initSideNav() { if (!navbar_initialized) { var $nav = $('nav'); // Add the offcanvas class to the navbar if it's not initialized $nav.addClass('navbar-offcanvas'); // Clone relevant navbars var $navtop = $nav.find('.navbar-top').first().clone(true); var $navbar = $nav.find('.navbar-collapse').first().clone(true); // Let's start with some empty vars var ul_content = ''; var top_content = ''; // Set min-height of the new sidebar to the screen height $navbar.css('min-height', window.screen.height); // Take the content of .navbar-top $navtop.each(function() { var navtop_content = $(this).html(); top_content = top_content + navtop_content; }); // Take the content of .navbar-collapse $navbar.children('ul').each(function() { var nav_content = $(this).html(); ul_content = ul_content + nav_content; }); // Wrap the new content inside an <ul> ul_content = '<ul class="navbar-nav sidebar-nav">' + ul_content + '</ul>'; // Insert the html content into our cloned content $navbar.html(ul_content); $navtop.html(top_content); // Append the navbar to body, // and insert the content of the navicons navbar just below the logo/nav-image $('body').append($navbar); $('.nav-image').after($navtop); // Set the toggle-variable to the Bootstrap navbar-toggler button var $toggle = $('.navbar-toggler'); // Add/remove classes on toggle and set the visiblity of the sidenav, // and append the overlay. Also if the user clicks the overlay, // the sidebar will close $toggle.on('click', function () { if (offCanvas.sidenav.sidenav_visible == 1) { $('html').removeClass('nav-open'); offCanvas.sidenav.sidenav_visible = 0; $('#overlay').remove(); setTimeout(function() { $toggle.removeClass('toggled'); }, 300); } else { setTimeout(function() { $toggle.addClass('toggled'); }, 300); // Add the overlay and make it close the sidenav on click var div = '<div id="overlay"></div>'; $(div).appendTo("body").on('click', function() { $('html').removeClass('nav-open'); offCanvas.sidenav.sidenav_visible = 0; $('#overlay').remove(); setTimeout(function() { $toggle.removeClass('toggled'); }, 300); }); $('html').addClass('nav-open'); offCanvas.sidenav.sidenav_visible = 1; } }); // Set navbar to initialized navbar_initialized = true; } } }; $(document).ready(function () { window_width = $(window).width(); nav_toggle = $('nav').hasClass('navbar-offcanvas') ? true : false; if (window_width < 992 || nav_toggle) { offCanvas.initSideNav(); } // Close the sidebar if the user clicks a link or a dropdown-item, // and close the sidebar $('.nav-link:not(.dropdown-toggle), .dropdown-item').on('click', function () { var $toggle = $('.navbar-toggler'); $('html').removeClass('nav-open'); offCanvas.sidenav.sidenav_visible = 0; setTimeout(function () { $toggle.removeClass('toggled'); }, 300); }); }); $(window).resize(function () { window_width = $(window).width(); // More responsive checks if the user resize the browser if (window_width < 992) { offCanvas.initSideNav(); } if (window_width > 992 && !nav_toggle) { $('nav').removeClass('navbar-offcanvas'); offCanvas.sidenav.sidenav_visible = 1; navbar_initialized = false; } });
该bootstrap4滑动侧边栏特效的codepen地址为:https://codepen.io/moso/pen/LjvRep