Skip to content

Instantly share code, notes, and snippets.

@cscuderi
Last active January 1, 2016 07:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cscuderi/8115544 to your computer and use it in GitHub Desktop.
Save cscuderi/8115544 to your computer and use it in GitHub Desktop.
A nice CSS3 sliding menu with fallback for older browsers.
<div id="outer-wrap">
<div id="inner-wrap">
<a id="nav-open-btn" class="menu-toggle" href="#nav">Toggle navigation</a>
<nav id="nav" class="main" role="navigation">
<div class="block">
<h2>Menu</h2>
<ul>
<li><a href="#">Information</a></li>
<li><a href="#">Contact</a></li>
<li><a href="#">Help</a></li>
</ul>
<a id="nav-close-btn" class="close-btn" href="#top-of-page">Return to content</a>
</div>
</nav>
</div><!--/inner-wrap-->
</div><!--/outer-wrap-->
/*!
*
* Copyright (c) David Bushell | http://dbushell.com/
* Code taken from Smashing Magazine (http://coding.smashingmagazine.com/2013/01/15/off-canvas-navigation-for-responsive-website)
*
*/
(function(window, document, undefined) {
window.App = (function() {
// helper functions
var trim = function(str) {
return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g,'');
};
var hasClass = function(el, cn) {
return (' ' + el.className + ' ').indexOf(' ' + cn + ' ') !== -1;
};
var addClass = function(el, cn) {
if (!hasClass(el, cn)) {
el.className = (el.className === '') ? cn : el.className + ' ' + cn;
}
};
var removeClass = function(el, cn) {
el.className = trim((' ' + el.className + ' ').replace(' ' + cn + ' ', ' '));
};
var hasParent = function(el, id) {
if (el) {
do {
if (el.id === id) {
return true;
}
if (el.nodeType === 9) {
break;
}
}
while((el = el.parentNode));
}
return false;
};
// normalize vendor prefixes
var doc = document.documentElement;
var transform_prop = window.Modernizr.prefixed('transform'),
transition_prop = window.Modernizr.prefixed('transition'),
transition_end = (function() {
var props = {
'WebkitTransition' : 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd otransitionend',
'msTransition' : 'MSTransitionEnd',
'transition' : 'transitionend'
};
return props.hasOwnProperty(transition_prop) ? props[transition_prop] : false;
})();
var _init = false, app = { };
var inner = document.getElementById('inner-wrap'),
nav_open = false,
nav_class = 'js-nav';
app.init = function() {
if (_init) {
return;
}
_init = true;
var closeNavEnd = function(e) {
if (e && e.target === inner) {
document.removeEventListener(transition_end, closeNavEnd, false);
}
nav_open = false;
};
app.closeNav =function() {
if (nav_open) {
// close navigation after transition or immediately
var duration = (transition_end && transition_prop) ? parseFloat(window.getComputedStyle(inner, '')[transition_prop + 'Duration']) : 0;
if (duration > 0) {
document.addEventListener(transition_end, closeNavEnd, false);
} else {
closeNavEnd(null);
}
}
removeClass(doc, nav_class);
};
app.openNav = function() {
if (nav_open) {
return;
}
addClass(doc, nav_class);
nav_open = true;
};
app.toggleNav = function(e) {
if (nav_open && hasClass(doc, nav_class)) {
app.closeNav();
} else {
app.openNav();
}
if (e) {
e.preventDefault();
}
};
// open nav with main "nav" button
document.getElementById('nav-open-btn').addEventListener('click', app.toggleNav, false);
// close nav with main "close" button
document.getElementById('nav-close-btn').addEventListener('click', app.toggleNav, false);
// close nav by touching the partial off-screen content
document.addEventListener('click', function(e)
{
if (nav_open && !hasParent(e.target, 'nav')) {
e.preventDefault();
app.closeNav();
}
},
true);
addClass(doc, 'js-ready');
};
return app;
})();
if (window.addEventListener) {
window.addEventListener('DOMContentLoaded', window.App.init, false);
}
})(window, window.document);
// ## ## ### ## ##
// ### ## ## ## ## ##
// #### ## ## ## ## ##
// ## ## ## ## ## ## ##
// ## #### ######### ## ##
// ## ### ## ## ## ##
// ## ## ## ## ###
#outer-wrap {
position: relative;
overflow: hidden;
width: 100%;
}
#inner-wrap {
position: relative;
width: 100%;
}
#nav {
z-index: 200;
position: relative;
overflow: hidden;
width: 100%;
color: #fff;
.close-btn {
display: none;}
.block-title {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
.block {
z-index: 2;
position: relative;
padding: 0.75em 1.25em;
background: #333333;
}
ul {
*zoom: 1;
display: block;
}
ul:before,
ul:after {
content: "";
display: table;
}
ul:after {
clear: both;
}
li {
display: block;
a {
display: block;
color: #ccc;
font-size: 0.875em;
line-height: 1.28571em;
font-weight: bold;
outline: none;
}
a:focus,
a:hover {
color: #fff;
background: rgba(255, 255, 255, 0.1);
}
&.is-active a {
color: #fff;
}
}
}
#nav {
position: absolute;
top: 0;
padding-top: 5.25em;
&:not(:target) {
z-index: 1;
height: 0;
}
&:target .close-btn {
display: block;}
.close-btn {
position: absolute;
top: -3.75em;
left: 1.875em;
}
.block {
position: relative;
padding: 0;
}
li {
position: relative;
border-top: 1px solid rgba(255, 255, 255, 0.1);
&:last-child {
border-bottom: 1px solid rgba(255, 255, 255, 0.1);}
&.is-active:after {
z-index: 50;
display: block;
content: "";
position: absolute;
top: 50%;
right: -0.03125em;
margin-top: -0.625em;
border-top: 0.625em transparent solid;
border-bottom: 0.625em transparent solid;
border-right: 0.625em white solid;
}
a {
padding: 0.85714em 2.14286em;}
}//li
}//#nav
.js-ready {
#nav {
height: 100%;
width: 70%;
background: #333333;
-webkit-box-shadow: inset -1.5em 0 1.5em -0.75em rgba(0, 0, 0, 0.25);
-moz-box-shadow: inset -1.5em 0 1.5em -0.75em rgba(0, 0, 0, 0.25);
box-shadow: inset -1.5em 0 1.5em -0.75em rgba(0, 0, 0, 0.25);
.block {
background: transparent;}
.close-btn {
display: block;
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70);
opacity: 0.7;
&:focus,
&:hover {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
}//#nav
}//.js-ready
#nav {
left: -70%;}
#inner-wrap {
left: 0;}
.js-nav #inner-wrap {
left: 70%;
}
//Animate menu & body on click
.csstransforms3d.csstransitions {
&.js-ready {
#nav {
left: 0;
-webkit-transform: translate3d(-100%, 0, 0);
-moz-transform: translate3d(-100%, 0, 0);
-ms-transform: translate3d(-100%, 0, 0);
-o-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
-o-backface-visibility: hidden;
backface-visibility: hidden;
}
#inner-wrap {
left: 0 !important;
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
-o-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
-webkit-transition: -webkit-transform 500ms ease;
-moz-transition: -moz-transform 500ms ease;
-o-transition: -o-transform 500ms ease;
transition: transform 500ms ease;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
-o-backface-visibility: hidden;
backface-visibility: hidden;
}
#nav .block {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70);
opacity: 0.7;
-webkit-transition: opacity 300ms 100ms, -webkit-transform 500ms ease;
-webkit-transition-delay: ease, 0s;
-moz-transition: opacity 300ms 100ms ease, -moz-transform 500ms ease;
-o-transition: opacity 300ms 100ms ease, -o-transform 500ms ease;
transition: opacity 300ms 100ms ease, transform 500ms ease;
-webkit-transform: translate3d(70%, 0, 0) scale3d(0.9, 0.9, 0.9);
-moz-transform: translate3d(70%, 0, 0) scale3d(0.9, 0.9, 0.9);
-ms-transform: translate3d(70%, 0, 0) scale3d(0.9, 0.9, 0.9);
-o-transform: translate3d(70%, 0, 0) scale3d(0.9, 0.9, 0.9);
transform: translate3d(70%, 0, 0) scale3d(0.9, 0.9, 0.9);
-webkit-transform-origin: 50% 0%;
-moz-transform-origin: 50% 0%;
-ms-transform-origin: 50% 0%;
-o-transform-origin: 50% 0%;
transform-origin: 50% 0%;
}
&.js-nav #nav .block {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
-o-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
&.js-nav #inner-wrap {
-webkit-transform: translate3d(70%, 0, 0) scale3d(1, 1, 1);
-moz-transform: translate3d(70%, 0, 0) scale3d(1, 1, 1);
-ms-transform: translate3d(70%, 0, 0) scale3d(1, 1, 1);
-o-transform: translate3d(70%, 0, 0) scale3d(1, 1, 1);
transform: translate3d(70%, 0, 0) scale3d(1, 1, 1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment