I have an off-canvas menu sliding from the left to cover the page. The building blocks of my page are divs. I call javascript functions to open and close the off-canvas menu. My main content remains as it is under the sliding menu. I have problems in finding a solution to dim the main content and to block any click to it.
I tried to use the property background: rgba(0, 0, 0, 0.5) !important; for an additional div with a z-index between off-canvas menu and maincontent, but without any result. Googled around, also here, but didn't find what I'm looking for. And I don't want to use Bootstrap or other libraries, to keep the project as light as possible. This is my code:
<style>
.sidenav {
height: 100%;
width: 220px;
position: absolute;
z-index: 999;
top: 0;
left: 0;
overflow-x: hidden;
-webkit-transform: translate3d(-220px,0,0);
-webkit-transition: -webkit-transform 0.4s;
-webkit-transition-timing-function: cubic-bezier(0.7,0,0.3,1);
}
.cover {
position: absolute;
z-index: 900;
left: 0px;
top: 0px;
display: none;
width: 100%;
height: 100%;
z-index: 900;
background: rgba(0, 0, 0, 0) !important;
display: none;
}
.maincontent {
position: relative;
z-index: 20;
margin: auto;
}
</style>
<script>
function openNav() {
document.getElementById("mySidenav").style.webkitTransform = "translate3d(-1px,0,0)";
document.getElementById("cover").style.display = "inline";
document.getElementById("cover").style.background = "rgba(0, 0, 0, 0.5) !important";
}
function closeNav() {
document.getElementById("mySidenav").style.webkitTransform = "translate3d(-220px,0,0)";
document.getElementById("cover").style.display = "none";
document.getElementById("cover").style.background = "rgba(0, 0, 0, 0) !important";
}
</script>
<div id="mySidenav" class="sidenav">
<a href="javascript:void(0)" id="closebtn" class="closebtn" onclick="closeNav()">×</a>
//menue items are hereunder
</div>
<div id="cover" class="cover">
<div id ="maincontent" class="maincontent">
//some elements here
<img id="open_nav" class="fixed-ratio-resize_menu" src="menu.png" alt="menu" onclick="openNav()">
//all the rest of the page is here
</div>
</div>
Now the menu slides in and out as needed, but I have problems in finding a neat and running solution for: 1) dim the main content area under the menu; 2) intercept any click on main content area and either ignore it either onclick close the menu; 3) block the y scrolling of the main content, since it pulls also the off canvas menu to follow it, thus giving the appearance of a truncated side menu area.
First move your main content div outside the cover div. Currently your main content will only be visible when the cover is visible:
function openNav() {
document.getElementById("mySidenav").style.webkitTransform = "translate3d(-1px,0,0)";
document.getElementById("cover").style.display = "inline";
// document.getElementById("cover").style.background = "rgba(0, 0, 0, 0.5) !important";
}
function closeNav() {
document.getElementById("mySidenav").style.webkitTransform = "translate3d(-220px,0,0)";
document.getElementById("cover").style.display = "none";
// document.getElementById("cover").style.background = "rgba(0, 0, 0, 0) !important";
}
.sidenav {
height: 100%;
width: 220px;
position: absolute;
z-index: 999;
top: 0;
left: 0;
overflow-x: hidden;
-webkit-transform: translate3d(-220px, 0, 0);
-webkit-transition: -webkit-transform 0.4s;
-webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1);
background: #fff;
}
.cover {
position: absolute;
z-index: 900;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 900;
background: rgba(0, 0, 0, .5) !important;
display: none;
}
.maincontent {
position: relative;
z-index: 20;
margin: auto;
}
<div id="mySidenav" class="sidenav">
<a href="javascript:void(0)" id="closebtn" class="closebtn" onclick="closeNav()">×</a> menu items are hereunder
</div>
<div id="cover" class="cover">
</div>
<div id="maincontent" class="maincontent">
some elements here<br>
<img id="open_nav" class="fixed-ratio-resize_menu" src="menu.png" alt="menu" onclick="openNav()"> all the rest of the page is here
</div>
Do you want to close the nav when clicking the cover? Then just add your onclick="closeNav()"
to the cover:
function openNav() {
document.getElementById("mySidenav").style.webkitTransform = "translate3d(-1px,0,0)";
document.getElementById("cover").style.display = "inline";
// document.getElementById("cover").style.background = "rgba(0, 0, 0, 0.5) !important";
}
function closeNav() {
document.getElementById("mySidenav").style.webkitTransform = "translate3d(-220px,0,0)";
document.getElementById("cover").style.display = "none";
// document.getElementById("cover").style.background = "rgba(0, 0, 0, 0) !important";
}
.sidenav {
height: 100%;
width: 220px;
position: absolute;
z-index: 999;
top: 0;
left: 0;
overflow-x: hidden;
-webkit-transform: translate3d(-220px, 0, 0);
-webkit-transition: -webkit-transform 0.4s;
-webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1);
background: #fff;
}
.cover {
position: absolute;
z-index: 900;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 900;
background: rgba(0, 0, 0, .5) !important;
display: none;
}
.maincontent {
position: relative;
z-index: 20;
margin: auto;
}
<div id="mySidenav" class="sidenav">
<a href="javascript:void(0)" id="closebtn" class="closebtn" onclick="closeNav()">×</a> menu items are hereunder
</div>
<div id="cover" class="cover" onclick="closeNav()">
</div>
<div id="maincontent" class="maincontent">
some elements here<br>
<img id="open_nav" class="fixed-ratio-resize_menu" src="menu.png" alt="menu" onclick="openNav()"> all the rest of the page is here
</div>
Finally, I would recommend to clean up your code and use event listeners instead of onclick properties in your html. Something like this:
var cover = document.getElementById("cover");
var sideNav = document.getElementById("mySidenav");
var closeNavBtn = document.getElementById("closebtn");
var openNavBtn = document.getElementById("open_nav");
function openNav() {
sideNav.style.webkitTransform = "translate3d(-1px,0,0)";
cover.style.display = "inline";
}
function closeNav() {
sideNav.style.webkitTransform = "translate3d(-220px,0,0)";
cover.style.display = "none";
}
closeNavBtn.addEventListener("click", closeNav);
cover.addEventListener("click", closeNav);
openNavBtn.addEventListener("click", openNav);
.sidenav {
height: 100%;
width: 220px;
position: absolute;
z-index: 999;
top: 0;
left: 0;
overflow-x: hidden;
-webkit-transform: translate3d(-220px, 0, 0);
-webkit-transition: -webkit-transform 0.4s;
-webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1);
background: #fff;
}
.cover {
position: absolute;
z-index: 900;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 900;
background: rgba(0, 0, 0, .5);
display: none;
}
.maincontent {
position: relative;
z-index: 20;
margin: auto;
}
<div id="mySidenav" class="sidenav">
<span id="closebtn" class="closebtn">×</span> menu items are hereunder
</div>
<div id="cover" class="cover">
</div>
<div id="maincontent" class="maincontent">
some elements here<br>
<img id="open_nav" class="fixed-ratio-resize_menu" src="menu.png" alt="menu"> all the rest of the page is here
</div>