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)
by junhui
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
/*
* 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
*
* The HTML elements' hierarchy:
* * root
* * .wrapper (relative)
* * nav (fixed, z-index: 1)
* * header (fixed, z-index: 1)
* * main
* * footer
* * .footer-top
* * .footer-bottom (fixed, z-index: -1)
* * .page-content-overlay (fixed: z-index: auto)
*
* And the stacking context hierarchy:
* * root stacking context
* * nav (fixed, z-index: 1)
* * header (fixed, z-index: 1)
* * .page-content-overlay (fixed, z-index: auto)
* * main, footer, .footer-top
* * .footer-bottom (fixed, z-index: -1)
*
* Read more about stacking context:
* https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
*/
.wrapper {
position: relative;
}
/*
* nav is fixed by default, when scrolling to the bottom, it turns to
* absolute for sticking above the footer (this done by Javascript).
*/
nav {
position: fixed;
top: 80px; /* top matches the fixed height of the header */
width: 240px; /* fixed width, this matches the main's margin-left */
height: 100vh; /* flexible height that rely on the viewpoint */
overflow: hidden;
/*
* a large enough vaule that makes sure the nav won't be covered
* by the page-content-overlay
*/
z-index: 1;
}
/* header always fixed in top */
header {
position: fixed;
top: 0;
width: 100%; /* full width */
/*
* fixed height, this matches:
* 1. the nav's top
* 2. the main's margin-top
* 3. the main's min-height
*/
height: 80px;
/*
* a large enough vaule that makes sure the header won't be covered
* by the page-content-overlay
*/
z-index: 1;
}
/* main */
main {
/*
* This makes the main working as expected in IE11.
*
* The HTML5 main element...
JavaScript
// Makes the sidebar nav sticky.
window.addEventListener("scroll", stickySidebarNavOnScrll)
var nav = document.querySelector("nav");
var mainHeight = document.querySelector("main").offsetHeight;
var headerHeight = document.querySelector("header").offsetHeight;
var footerTopHeight = document.querySelector(".footer-top").offsetHeight;
function stickySidebarNavOnScrll() {
var screenHeight = screenSize()[1];
var scrollTop = pageOffset()[1];
var offset = scrollTop + screenHeight - headerHeight - mainHeight
// Use element's style property to pass the CSP style-src policy.
//
// > However, styles properties that are set directly on the element's
// style property will not be blocked, allowing users to safely
// manipulate styles via Javascript:
//
// Read more: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src#Violation_cases
if (offset > 0) {
nav.style.top = "calc(100% - " + nav.offsetHeight + "px - " + footerTopHeight + "px)"
nav.style.position = "absolute"
} else {
nav.style.top = ""
nav.style.position = ""
}
}
// page-content-overlay trigger demo
var contentOverlayTigger = document.querySelector("#page-content-overlay-trigger");
var contentOverlay = document.querySelector(".page-content-overlay");
contentOverlayTigger.addEventListener("click", function () {
if (!contentOverlay.classList.contains("open")) {
contentOverlay.classList.add("open");
} else {
contentOverlay.classList.remove("open");
}
})
///////////////////////////////
// Helpers
// Cross-browser method for detecting the scrollTop of the
// browser window:
// https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollY#Notes
function pageOffset() {
var supportPageOffset = window.pageXOffset !== undefined;
var isCSS1Compat = ((document.compatMode || "") === "CSS1Compat");
var x = supportPageOffset ? window.pageXOffset :...