CSS only push-out menu
by moob
HTML
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<div id="nav">
<label class="burger" for="nav-trigger">☰</label><!-- consider #8801 -->
<ul>
<li><a href="#">Menu Item</a></li>
<li><a href="#">This Thing</a></li>
<li><a href="#">Another Thing</a></li>
<li><a href="#">Something Else</a><input type="checkbox" id="submenu1" /><label for="submenu1"></label><ul>
<li><a href="#">Sub Item</a></li>
<li><a href="#">This Thing</a></li>
<li><a href="#">Sub Item</a></li>
<li><a href="#">This Thing</a></li>
</ul></li>
<li><a href="#">Kittens</a></li>
<li><label for="nav-trigger">☰ → Close Menu</label></li>
</ul>
</div>
<div id="main">
<h1>CSS Push-out Menu</h1>
<p>This push out menu uses a checkbox and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/General_sibling_selectors">general sibling selectors</a> to determine if the menu is shown.</p>
<p>At the time of writing this is untested but should be supported all modern browsers (ie9 up) and work on touch devices too. <=ie8 needs js to support css `:checked` selector. Selectivizr does this.</p>
NOTES TO SELF:
<ul>
<li>General sibling selector (~) support is excellent (ie7+)</li>
<li>but :checked is not. Add Selectivizr or similar to this demo</li>
<li>nested menus were not closable in build <=15 but I dont much like this checkbox solution as it makes the menu ugly. Perhaps there's a better way?</li>
</ul>
NOTES TO USER:
<ul>
<li>Want the menu to be open on load? Just set <code>nav-trigger</code> input to <code>selected</code>.</li>
</ul>
<hr />
<p>Aenean lacinia bibendum nulla sed consectetur. Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Donec sed odio dui. Vestibulum id ligula...
CSS
*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;}
html, body { height: 100%; width: 100%; font-family: Helvetica, Arial, sans-serif;}
body {overflow-x: hidden;}
/* #nav-trigger is a hidden input */
#nav-trigger {
position: absolute;
clip: rect(0, 0, 0, 0);
visibility:hidden;
}
/* The nav itself (off-screen by default) */
#nav {
width: 300px;
max-width:80%;
height: 100%;
position: absolute;
top: 0;
right:-300px;
bottom: 0;
z-index: 10;
list-style: none;
background: #111;
}
#nav label.burger {
width:30px;
height:30px;
display:block;
position: absolute;
top: 30px;
left:-60px;
color:#000;
font-size:30px;
line-height:30px;
-webkit-font-smoothing:none;
font-smoothing:none;
font-weight:bold;
cursor:pointer;
transition: color 0.2s, transform 0.4s;
}
#nav label.burger:hover {
color:#fff;
}
#nav ul {
margin:0;
padding:0;
display:block;
position:relative;
height:100%;
top:0;
right:0;
overflow:auto;
}
#nav li {
display:block;
position:relative;
margin:1px 0;
padding:0;
}
#nav li a, #nav li label[for='nav-trigger'] {
display: block;
padding: 1em;
background: #333;
color: white;
font-size:1.2em; line-height:1.2em;
text-decoration: none;
transition: color 0.2s, background 0.5s;
}
#nav li label {color:#999;}
#nav li a:hover, #nav li label:hover {
color: rgb(160,216,239);
background: #444;
}
#nav ul ul {opacity:0.7; height:inherit; overflow:visible;}
#nav ul ul li {
display:block;
max-height:0; overflow:hidden; margin:0; text-indent:20px;
-webkit-transition: max-height 0.2s;
transition: max-height 0.2s;
}
#nav ul li input {
position: absolute;
clip: rect(0, 0, 0, 0);
visibility:hidden;
}
#nav ul li input+label {
-webkit-font-smoothing:none;
font-smoothing:none;
...
JavaScript
/*
TO DO:
Create JS inplementation of :checked for <IE9
*/