JSFiddle - React, Tailwind, and code Playground
HTML
<body id="#top">
<nav>
<ul>
<li><a href="#top">Home</a></li>
<li><a href="#web">Web</a></li>
<li><a href="#design">Design</a></li>
<li><a href="#photo">Photo</a></li>
</ul>
</nav>
<header><h2>HEADER</h2></header>
<section id="web"><h2>WEB</h2></section>
<section id="design"><h2>DESIGN</h2></section>
<section id="photo"><h2>PHOTO</h2></section>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</body>
CSS
/*GENERAL*/
* {
margin: 0;
padding: 0;
box-sizing: border-box;
position: relative;
overflow: hidden;
}
html {
overflow: auto;
}
/*SPECIFIC*/
body {
background-color: white;
font-family: sans-serif;
}
header {
background-color: #2196F3;
height: 50vh;
padding: 100px 40px;
}
nav {
position: fixed;
z-index: 99;
text-align: center;
width: 100%;
background-color: #eee;
}
nav ul {
display: block;
margin: auto;
text-align: center;
list-style: none;
}
nav li {
display: inline-block;
padding: 10px 20px;
}
nav a {
text-decoration: none;
color: inherit;
font-size: 20px;
}
nav a.current {
color: #2196F3;
}
section {
width: 100%;
height: 100vh;
padding: 100px 40px;
}
section:nth-child(even) {
background-color: #2196F3;
}
JavaScript
/*indent: 4*/
/*global $, console, alert*/
var currentTab = (function () {
"use strict";
//variables
var $window = $(window),
$section = $('section'),
$scrollPosition = $window.scrollTop(),
$sectionHeights = [];
//will calculate each section heights and store them in sectionHeights[] array
function resizeSectionHeights() {
$section.each(function (i) {
$sectionHeights[i] = $(this).outerHeight();
});
}
/*will calculate current scroll position. If it's between the top and bottom of a section,
the tab containing an href value of that section id will have the .current class.*/
function applyCurrentState() {
$scrollPosition = $window.scrollTop();
$section.each(function (i) { //we indent i at each section count, so we can find it's height in sectionHeight[]
var $anchor = $("nav a[href=#" + $(this).attr('id') + "]"),
$sectionTop = $(this).offset().top - 1, // -1 get rid of calculation errors
$sectionBottom = $sectionTop + $sectionHeights[i] - 1; // -1 get rid of calculation errors
if ($scrollPosition >= $sectionTop && $scrollPosition < $sectionBottom) {
$anchor.addClass('current');
} else {
$anchor.removeClass('current');
}
});
}
//binding events
$window.resize(resizeSectionHeights);
$window.scroll(applyCurrentState);
//initialization
resizeSectionHeights();
}());