The following code has been tested on the latest chromium, on Opera Mini, on Safari for IOS 7 and finally, on the default web browser on android 2.3.3.
As you may already know, the CSS overflow
rule isnt supported on android 2.3.3 which makes sidenavs un-scrollable.
Well, guess what? I found a workaround. See the following code:
//Import element
cont=document.getElementById("content");
nav=document.getElementsByClassName("navbar");
opt=document.getElementsByClassName("option");
side=document.getElementById("sidenav");
side.style.display="none";
navtog();
function showhide(x){
if("transform" in document.body.style)
{
x.classList.toggle("change");
}
//If sidenav open
if(cont.style.left=="150px"){
//Sidenav stuff
//Store sidenav pos
sidepos=window.scrollY;
//Move sidenav to pos (to remove wierd chunky animations)
side.style.position="fixed";
side.style.top="-"+sidepos+"px";
cont.style.left="";
cont.style.position="";
cont.style.top="0px";
nav[0].style.left="0px";
//Scroll back to user pos
window.scrollTo(0,pos);
setTimeout(function() {
side.style.display="none";
}, 200);
}else{//sidenav closed
//Store user POS
pos=this.scrollY;
cont.style.position="fixed";
cont.style.left="150px";
cont.style.top="-"+pos+"px";
nav[0].style.left="150px";
side.style.display="block";
//Make sidenav scrollable again
side.style.top="";
side.style.position="";
if(typeof sidepos === 'undefined'){
sidepos=0;
}
window.scrollTo(0,0);
}
}
window.onscroll = function() {navtog()};
function navtog(){
if(cont.style.left==""){
if(this.scrollY<1){
nav[0].className="navbar";
}else{
nav[0].className="navbar shad";
}
}
}
function bhov(el) {
var els = Array.prototype.slice.call( document.getElementsByClassName('option'), 0 );
opt[els.indexOf(event.currentTarget)].className="option o-a";
}
function bbay(el) {
var els = Array.prototype.slice.call( document.getElementsByClassName('option'), 0 );
opt[els.indexOf(event.currentTarget)].className="option o-o";
}
body{
font-family:Helvetica, sans-serif;
margin:0;
color:white;
background:#23272a;
overflow-x:hidden;
}
/*Layout*/
#sidenav{
/*Important*/
width:150px;
float:left;
background:#23272a;
}
#content{
float:left;
width:100%;
position:absolute;
left:0;
padding-top:40px;
background:#2c2f33;
-webkit-transition:left 0.2s ease-out;
-moz-transition:left 0.2s ease-out;
-ms-transition:left 0.2s ease-out;
transition:left 0.2s ease-out;
-moz-box-shadow:0 0 20px rgba(0,0,0,0.5);
-webkit-box-shadow:0 0 20px rgba(0,0,0,0.5);
box-shadow:0 0 20px rgba(0,0,0,0.5);
}
/*Buttons*/
.option{
text-decoration:none;
display:block;
color:#99aab5;
line-height:14px;
font-size:12px;
padding:10px;
}
.o-a{/*ACTIVE*/
color:white;
}
.o-o{/*OFF*/
color:#99aab5;
-webkit-transition:color 0.2s ease-out;
-moz-transition:color 0.2s ease-out;
-ms-transition:color 0.2s ease-out;
transition:color 0.2s ease-out;
}
/*Navbar*/
.navbar{
position:fixed;
top:0;
left:0;
width:100%;
height:40px;
/*style*/
-webkit-transition:left 0.2s ease-out,background 0.2s;
-moz-transition:left 0.2s ease-out,background 0.2s;
-ms-transition:left 0.2s ease-out,background 0.2s;
transition:left 0.2s ease-out,background 0.2s;
}
.shad{background:#99aab5;}
/*Logo*/
.navbar img{
display:block;
margin:0 auto;
padding:5px;
height:30px;
}
/*Ham menu*/
.ham{
width:40px;
height:28px;
position:absolute;
top:5px;
left:5px;
/*style*/
border:1px solid white;
border-radius:3px;
cursor:pointer;
}
.bar1, .bar2, .bar3 {
width: 30px;
height: 4px;
background: white;
margin: 4px 5px;
transition: 0.4s;
border-radius:3px;
}
.change .bar1 {/*Gauche Haut*/
transform: rotate(45deg) translate(8px, -3px);
width:16px;
}
.change .bar2 {opacity: 0;}
.change .bar3 {
transform: rotate(-45deg) translate(8px, 3px);
width:16px;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" charset="utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="page">
<div id="sidenav">
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #1</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #2</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #3</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #4</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #5</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #6</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #7</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #8</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #9</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #10</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #11</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #12</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #13</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #14</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #15</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #16</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #17</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #18</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #19</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #20</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #21</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #22</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #23</a>
<a href="javascript:void(0);" class="option" onmouseover="bhov(this)" onmouseout="bbay(this)">Option #24</a>
</div>
<div id="content">
<div class="navbar">
<div class="ham" onclick="showhide(this);">
<div class="bar1"></div>
<div class="bar2"></div>
<div class="bar3"></div>
</div>
<img src="https://proxy.duckduckgo.com/ip3/codereview.stackexchange.com.ico">
</div>
this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br><a href="javascript:showhide();">showhide();</a>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>this is some content<br>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
How it works:
The page content (were the dummy content is+navbar) is set at width="100%"
when clicking on the hamburger menu, heres what happens
1) We store the user scroll position before changing anything
2) We set the page content to position="fixed"
3) We add the following property to the content: top="(page scroll position)";
4) We make the sidenav go display="block"
(if its not set as none when closed, sometimes, old browsers will click on the sidenav buttons even if closed)
5) The page content goes left:150px
(Lets not forget that CSS makes it transition between the two stages which makes it look real good)
6) We also make the navbar go left:150px
cause on old browsers, it doesnt moves (or glitches/stretches if youre on iOS 7 safari)
7) The sidenav is now scrollable and the page content isnt. Yay!
8) (optional) cool ass hover effect for items in the sidenav.
When closing the sidenav
Pretty much the reverse thing but we add those steps:
1) The animation between open and closed lasts 0.2 seconds. Keep that in mind.
2) We store the user's scroll position
We add the following properties to the sidenav:
3) Position="fixed"
4) top="(scroll pos)"
Wait 0.2 seconds
5) display="none"
SO thats pretty much how it works... I may have brushed over some details tho, bare with me please, haha.
Any suggestions? Ideas? Toughts? Do you think this could be used as production code?