Desktop layout prototype
Requirement:
1. (left) sidebar nav is sticky
2. header is fixed in the top
3. footer has the "uncover the black bit by scrolling up"
4. page-content-overlay for covering the main and footer
(Tested in IE11/Chrome/Firefox/Safari)
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Desktop Layout Prototype</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" media="screen" href="main.css" />
</head>
<body>
<div class="wrapper">
<nav>
Sidebar navigation (sticky)
<br />
<button id="page-content-overlay-trigger">Toogle the page-content-overlay</button>
<br /> Menu Item
<br /> Menu Item
<br /> Menu Item
<br /> Menu Item
<br /> Menu Item
<br /> Menu Item
<br /> Menu Item
<br /> Menu Item
<br /> Menu Item
<br /> Menu Item
<br /> Menu Item
</nav>
<header>
Header (fixed)
</header>
<main>
START
<br /> Lorem ipsum dolor sit, amet consectetur adipisicing elit. In nisi nihil commodi odit iure rerum eveniet non
enim deleniti ipsam esse reprehenderit neque, nostrum voluptate exercitationem suscipit? Repellat consectetur
iure magnam porro similique possimus expedita quas tempora! Magnam voluptate voluptatum inventore aliquam amet
pariatur accusamus, iusto repudiandae ab nobis aperiam! Nesciunt nemo ullam iste quasi veritatis numquam, magnam
odio consectetur quia exercitationem dolor quae amet quibusdam laudantium veniam suscipit sint vel est doloremque
totam laborum voluptates quidem aliquam! A architecto, consequatur dolores minus porro quae? Officia reprehenderit
iste eius pariatur labore quod dolore eum omnis, error illo totam ducimus hic qui accusamus, quidem enim doloribus
fugit atque vitae, minus ratione provident exercitationem incidunt. Et, nemo optio. Ab esse distinctio dolor
tempore placeat, eligendi natus...
CSS
/* Requirements:
* 1. Header is fixed in the top
* 2. Header has a menu button for opening/closing the left sidebar
* nav menu
* 3. Tap on the menu button, the left sidebar nav appeared by pushing
* the content to the right
* 4. Tap on the menu button again or the content will pushing
* the nav and content back to the left
*
* The HTML elements' hierarchy:
* * root
* * .wrapper (absolute, z-index: auto)
* * .sub-wrapper (absolute, z-index: auto)
* * nav (absolute, z-index: auto)
* * .nav-inner-wrapper (absolute, z-index: auto)
* * header (relative, z-index: 1)
* * .page-content-wrapper
* * main
* * footer
*
* And the stacking context hierarchy:
* * root stacking context
* * header (relative, z-index: 1)
* * nav
* * .page-content-wrapper (main, footer)
*
* Read more about stacking context:
* https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
*/
/* Utilites */
/*
* The absolute-layer is useful to create an inner scrollable layer,
* read more from:
* https://medium.com/@im_rahul/safari-and-position-fixed-978122be5f29
*/
.absolute-layer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.scrollable-y {
-webkit-overflow-scrolling: touch;
overflow-y: auto;
}
/* Toggle Menu */
/* Both .wrapper and .sub-wrapper is an absolute layer */
.wrapper.menuIsOpen {
overflow: hidden;
}
.sub-wrapper {
transition: transform 0.3s ease-out;
}
.wrapper.menuIsOpen>.sub-wrapper {
transform: translateX(240px);
}
/* Left sidebar - Nav */
/*
* Notes:
* 1. Left sidebar sits in the left side of the content, it's
* invisible by default. When the menu is open, it pushes the
* sub-wrapper right to let the nav visible in the viewpoint.
* 2. nav's inner wrapper should be an abosolute layer and
* scrollable.
*/
nav {
width: 240px;
/* Fixed width */
position: absolute;
top: 0;
bottom: 0;
...
JavaScript
const menuButton = document.querySelector("#menuButton");
const wrapper = document.querySelector(".wrapper");
const pageContent = document.querySelector(".page-content-wrapper");
/* Toggle Menu */
menuButton.addEventListener("click", function() {
if (wrapper.classList.contains("menuIsOpen")) {
wrapper.classList.remove("menuIsOpen");
} else {
wrapper.classList.add("menuIsOpen");
}
})
/* Touch the page content close the menu */
pageContent.addEventListener("touchstart", function(event) {
if (wrapper.classList.contains("menuIsOpen")) {
// Prevent the origin bounce effect, read more:
// https://stackoverflow.com/a/7771215
event.preventDefault();
wrapper.classList.remove("menuIsOpen");
}
});