JSFiddle - React, Tailwind, and code Playground
HTML
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Navigation</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="nav__bar">
<a href="#" class="nav__trigger">
<div class="bars"></div>
</a>
</div>
<main class="main">
<div id="block_1" class="block">
<h1>Block 1</h1>
</div>
<div id="block_2" class="block">
<h1>Block 2</h1>
</div>
<div id="block_3" class="block">
<h1>Block 3</h1>
</div>
</main>
<nav class="nav">
<ul class="nav__list">
<li class="nav__item"><a href="#block_1">Block 1</a></li>
<li class="nav__item"><a href="#block_2">Block 2</a></li>
<li class="nav__item"><a href="#block_3">Block 3</a></li>
</ul>
</nav>
<script src='https://cdnjs.cloudflare.com/ajax/libs/classlist/2014.01.31/classList.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/iamdustan-smoothscroll/0.4.0/smoothscroll.js'></script>
<script src="js/index.js"></script>
</body>
</html>
CSS
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400|Raleway:300,700);
*,
*:before,
*:after {
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
html {
font-family: "Open Sans", Helvetica, arial, sans-serif;
color: #333333;
background-color: #eeeeee;
}
body.is-froze {
overflow: hidden;
width: 100vw;
height: 100vh;
}
h1, h2, h3,
h4, h5, h6 {
font-family: "Raleway", "Open Sans", sans-serif;
}
a {
color: #333333;
text-decoration: none;
}
img {
max-width: 100%;
}
a {
-webkit-transition: color 0.3s ease-in-out;
transition: color 0.3s ease-in-out;
}
a:hover {
color: #7d87a8;
}
.main {
overflow: hidden;
position: relative;
width: 100%;
width: calc(100% - 60px);
height: 100vh;
margin-left: 60px;
background-color: #eeeeee;
-webkit-transition: 0.55s cubic-bezier(0.645, 0.045, 0.355, 1);
transition: 0.55s cubic-bezier(0.645, 0.045, 0.355, 1);
-webkit-transform: scale(1) translate3d(0, 0, 0);
transform: scale(1) translate3d(0, 0, 0);
-webkit-clip-path: inset(0 0 0 0);
clip-path: inset(0 0 0 0);
will-change: width, height, opacity, transform, clip-path;
z-index: 1;
}
.main.is-active {
overflow: hidden;
height: 100vh;
width: 100vw;
width: calc(100vw - 60px);
pointer-events: none;
opacity: 0.25;
-webkit-transform: scale(0.9) translate3d(60%, 0, 0);
transform: scale(0.9) translate3d(60%, 0, 0);
}
@media (min-width: 600px) {
.main.is-active {
-webkit-transform: scale(0.9) translate3d(40%, 0, 0);
transform: scale(0.9) translate3d(40%, 0, 0);
}
}
.main.is-transition-out {
-webkit-clip-path: inset(0 0 0 100%);
clip-path: inset(0 0 0 100%);
}
.content {
max-width: 800px;
margin: 0 auto;
}
.nav__bar {
position: fixed;
top: 0;
bottom: 0;
left: 0;
width: 60px;
height: 100vh;
border-right: 1px solid rgba(125, 135, 168, 0.25);
background-color: #191b22;
z-index: 99;
}
.nav__trigger {
display:...
JavaScript
var navigation = {
// Variables
$navTrigger: document.querySelector('.nav__trigger'),
$nav: document.querySelector('.nav'),
$navItems: document.querySelectorAll('.nav__item a'),
$main: document.querySelector('.main'),
transitionEnd: 'webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',
isOpeningNav: false,
init: function init() {
var self = this;
// Reset overflow and height on load
self.$main.style.overflow = 'auto';
self.$main.style.height = 'auto';
// Handle scroll events
window.addEventListener('scroll', function (e) {
if (window.scrollY == 0 && self.isOpeningNav) {
self.isOpeningNav = false;
// Add a small delay
setTimeout(function () {
self.openNavigation();
}, 150);
}
});
// Handle .nav__trigger click event
self.$navTrigger.addEventListener('click', function (e) {
e.preventDefault();
if (!self.$navTrigger.classList.contains('is-active')) {
if (window.scrollY !== 0) {
// Scroll to top
window.scroll({ top: 0, left: 0, behavior: 'smooth' });
// Enable opening nav
self.isOpeningNav = true;
} else {
self.openNavigation();
}
} else {
self.closeNavigation();
}
});
// Handle .nav__item click events
self.$navItems.forEach(function (navLink) {
navLink.addEventListener('click', function (e) {
e.preventDefault();
// Remove is-active from all .nav__items
self.$navItems.forEach(function (el) {
el.classList.remove('is-active');
});
// Ad is-active to clicked .nav__item
...