JSFiddle - React, Tailwind, and code Playground

by Brian Peacock

HTML

<div id="box-1">
    <div class="nav">
        <span class="box-1">Box 1</span>
        <span class="box-2">Box 2</span>
        <span class="box-3">Box 3</span>
        <span class="box-4">Box 4</span>
    </div>
    <span class="legend">Box 1</span>
</div>
<div id="box-2">
    <div class="nav">
        <span class="box-1">Box 1</span>
        <span class="box-2">Box 2</span>
        <span class="box-3">Box 3</span>
        <span class="box-4">Box 4</span>
    </div>
    <span class="legend">Box 2</span>
</div>
<div id="box-3">
    <div class="nav">
        <span class="box-1">Box 1</span>
        <span class="box-2">Box 2</span>
        <span class="box-3">Box 3</span>
        <span class="box-4">Box 4</span>
    </div>
    <span class="legend">Box 3</span>
</div>
<div id="box-4">
    <div class="nav">
        <span class="box-1">Box 1</span>
        <span class="box-2">Box 2</span>
        <span class="box-3">Box 3</span>
        <span class="box-4">Box 4</span>
    </div>
    <span class="legend">Box 4</span>
</div>

CSS

html {
    font-size:18px;
    box-sizing:border-box;
}
*, *:before, *:after {
    padding:0;
    margin:0;
    box-sizing:inherit;
}
body {
    color:#000;
    background:#000;
}
div[id|="box"] {
    width:90%;
    height:500px;
    background:#d8d8d8;
    border:1px solid #999;
    margin:1.5rem auto;
    clear:both;
    display:block;
}
div[id|="box"]:nth-of-type(3n+2) {
    background:#ffd8d8;
}
div[id|="box"]:nth-of-type(3n+3) {
    background:#c8d8ff;
}

.nav {
    width:100%;
    font-size:1rem;
    background:#fff;
    line-height:2rem;
    border-bottom:1px solid #666;
    display:block;
}
.nav span[class|="box"] {
    width:25%;
    color:inherit;
    background:inherit;
    text-align:center;
    border-right:1px solid #666;
    display:inline-block;
    cursor:pointer;
    float:left;
    transition:all 444ms ease-in;
}
.nav span[class|="box"]:last-of-type {
    border-right:0;
}
.nav span[class|="box"]:hover {
    color:#fff;
    background:#999;
}
.legend {
    font-size:2rem;
    font-weight:bold;
    text-align:center;
    margin:33% auto 0;
    clear:both;
    display:block;
}

JavaScript

/* setting event listeners for clas=box-? */
var navSpans = [].slice.call(document.querySelectorAll('span[class|="box"]'));
navSpans.filter(function(n) {
    n.addEventListener('click', jumpTo, true);
});

/* catch onclick events and pass to scroll.To */
function jumpTo(e) {
    scroll.To(e.target.className);
}


/* scroll to target */
var scroll = (function() {

    var elementPosition = function(a) {
        return function() {
            return a.getBoundingClientRect().top;
        };
    };

    var scrolling = function( elementID ) {

        var el = document.getElementById( elementID ),
            elPos = elementPosition( el ),
            duration = 300,
            increment = Math.round( Math.abs( elPos() )/50 ),
            time = Math.round( duration/increment ),
            last = 0,
            E;

        function scroller() {
            E = elPos();
            
            if (E === last) {
                return;
            } else {
                last = E;
            }

            increment = (E > -20 && E < 20) ? ((E > - 5 && E < 5) ? 1 : 5) : increment;

            if (E > 1 || E < -1) {

                if (E < 0) {
                    window.scrollBy( 0,-increment );
                } else {
                    window.scrollBy( 0,increment );
                }

                setTimeout(scroller, time);

            } else {

                el.scrollTo( 0,0 );

            }
        }

        scroller();
    };

    return {
        To: scrolling
    }

})();