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");
  }
});