Skip to content

Instantly share code, notes, and snippets.

@joshbeckman
Created January 4, 2014 22:18
Show Gist options
  • Save joshbeckman/8261489 to your computer and use it in GitHub Desktop.
Save joshbeckman/8261489 to your computer and use it in GitHub Desktop.
General-purpose hidden menu with animation, button animation, responsive styling. Woot.
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-type" />
<title>Hidden Menu Demo</title>
<meta content="width=device-width, initial-scale=1" name="viewport" />
<style type="text/css">
body{
margin:0;
background:coral;
}
#main-menu-button{
color: #aaa;
cursor: pointer;
position: fixed;
background: transparent;
border: none;
font-size: 2em;
width: 2em;
height: 1.5em;
left: 0;
padding-right: 0.5em;
padding-left: 0.5em;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
transition: all 0.3s ease;
}
.menu {
background: rgba(255,255,255,1);
position: fixed;
overflow-y: auto;
}
.menu h3 {
color: darkgrey;
padding: 0px 0px;
margin: 0;
}
.menu a {
display: block;
}
.menu p {
margin-left: 1em;
}
.menu small a:hover{
background-color: transparent;
}
.menu a:hover {
background: #ddd;
color: black;
}
.menu a:active {
}
.menu-vertical {
width: 240px;
height: 100%;
top: 0;
z-index: 1000;
}
.menu-vertical a {
padding: 0.25em 1em;
}
/* Vertical menu that slides from the left or right */
.menu-left {
left: -240px;
}
.menu-left.menu-open {
left: 0px;
box-shadow: -3px 0 3px 0px rgba(0,0,0,0.1);
}
#main-menu-button.menu-open {
right: 240px;
color: black;
}
/* Transitions */
.menu,
.menu-push {
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
transition: all 0.3s ease;
}
#main-menu-button span {
position: fixed;
cursor: pointer;
top: 30px;
left: 20px;
display: block;
width: 30px;
height: 4px;
margin-top: -2px;
background-color: white;
font-size: 0px;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-transition: 0.3s;
transition: 0.3s;
}
#main-menu-button span:before,
#main-menu-button span:after {
position: absolute;
left: 0px;
width: 100%;
height: 100%;
background: white;
content: '';
-webkit-transition: -webkit-transform 0.3s;
transition: transform 0.3s;
}
#main-menu-button span:before {
-webkit-transform: translateY(-250%);
transform: translateY(-250%);
}
#main-menu-button span:after {
-webkit-transform: translateY(250%);
transform: translateY(250%);
}
#main-menu-button.menu-open span{
background-color: transparent;
left: 250px;
}
#main-menu-button.menu-open span:before {
-webkit-transform: translateY(0) rotate(45deg);
transform: translateY(0) rotate(45deg);
}
#main-menu-button.menu-open span:after {
-webkit-transform: translateY(0) rotate(-45deg);
transform: translateY(0) rotate(-45deg);
}
@media screen and (max-height: 26.375em){
.menu-vertical {
font-size: 90%;
width: 190px;
}
.menu-left {
left: -190px;
}
#main-menu-button.menu-open span{
left: 190px;
}
}
</style>
</head>
<body>
<div id="layout">
<button id="main-menu-button" class="menu-toggle-button">
<span>Menu</span>
</button>
<nav id="menu-left" class="menu menu-vertical menu-left">
<a href="#">Cool, a link</a>
<p>Or text. That's cool, too.</p>
</nav>
</div>
<script type="text/javascript">
// Menu Control functions
(function(window, document){
var menu = document.getElementById( 'menu-left' ),
menuTogglers = document.getElementsByClassName( 'menu-toggle-button' ),
menuButton = document.getElementById( 'main-menu-button' ),
menuTimeout,
menuToggle = function() {
for(i=0;i<menuTogglers.length;i++){
classie.toggle( menuTogglers[i], 'active' );
}
classie.toggle( menu, 'menu-open' );
if(menuButton){classie.toggle( menuButton, 'menu-open' );}
};
if(menuButton){
menu.onmouseout = function () {
menuTimeout = window.setTimeout(menuToggle, 500);
};
menu.onmouseover = function(){
window.clearTimeout(menuTimeout);
};
menuButton.onclick = function(){
menuToggle();
};
}
function makeToggleClickFxn() {
return function() {
menuToggle();
};
}
for(i=0;i<menuTogglers.length;i++){
menuTogglers[i].onclick = makeToggleClickFxn();
}
})(this, this.document);
// Classie helper function
( function( window ) {
'use strict';
// class helper functions from bonzo https://github.com/ded/bonzo
function classReg( className ) {
return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
}
// classList support for class management
// altho to be fair, the api sucks because it won't accept multiple classes at once
var hasClass, addClass, removeClass;
if ( 'classList' in document.documentElement ) {
hasClass = function( elem, c ) {
return elem.classList.contains( c );
};
addClass = function( elem, c ) {
elem.classList.add( c );
};
removeClass = function( elem, c ) {
elem.classList.remove( c );
};
}
else {
hasClass = function( elem, c ) {
return classReg( c ).test( elem.className );
};
addClass = function( elem, c ) {
if ( !hasClass( elem, c ) ) {
elem.className = elem.className + ' ' + c;
}
};
removeClass = function( elem, c ) {
elem.className = elem.className.replace( classReg( c ), ' ' );
};
}
function toggleClass( elem, c ) {
var fn = hasClass( elem, c ) ? removeClass : addClass;
fn( elem, c );
}
var classie = {
// full names
hasClass: hasClass,
addClass: addClass,
removeClass: removeClass,
toggleClass: toggleClass,
// short names
has: hasClass,
add: addClass,
remove: removeClass,
toggle: toggleClass
};
// transport
if ( typeof define === 'function' && define.amd ) {
// AMD
define( classie );
} else {
// browser global
window.classie = classie;
}
})( window );
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment