JSFiddle - React, Tailwind, and code Playground

by lupos

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
<div id="header">
    <h1>TIME</h1>
</div>
<div id="notTheHeader" class="scrollable">
    <div id="pushDown">
        PUSH DOWN
    </div>
    <div id="magazineImage">
        <img src="http://img.timeinc.net/time/magazine/archive/covers/2014/1101140127_600.jpg" alt=""/>
    </div>
    <div class="wrapper">
        <div id="content" class="noScroll scrollable">
            <div class="wrapper">
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent at nisi non eros suscipit laoreet a eget lectus. Donec aliquam risus in ante tincidunt fringilla. Nunc ultricies odio nec elementum hendrerit. In tristique quis metus vel tristique. Praesent facilisis bibendum ultrices. Maecenas lectus felis, luctus vel ligula sed, ornare convallis nisl. Vestibulum vitae nulla eros. Aenean ac blandit nulla. Fusce scelerisque ac ipsum quis accumsan. Cras ullamcorper odio id dolor vulputate tristique a nec augue. Fusce suscipit dui id sollicitudin fringilla. Aenean nisi dolor, hendrerit id tellus ut, interdum commodo urna. Nunc auctor augue eget neque elementum dignissim sed bibendum lectus. Aenean euismod, velit nec aliquam elementum, odio massa condimentum nisl, et vulputate nibh nulla at mi. Aliquam vehicula eros eu lorem commodo semper.</p>
    
                <p>Fusce a odio ac risus pulvinar molestie. Ut pellentesque ultricies magna, eu iaculis lectus sollicitudin in. Morbi fermentum neque ut tellus pellentesque, eu pellentesque velit consequat. Pellentesque nec turpis faucibus, dapibus elit eget, tincidunt libero. Curabitur mattis velit tincidunt sapien elementum molestie elementum nec tellus. Ut at tempor erat, vitae cursus nulla. Maecenas luctus lacinia felis a dapibus. Duis tempus nisl in pretium pellentesque. Sed porta tincidunt est. Proin eu neque gravida, aliquam ante at, porttitor enim. Vivamus ullamcorper lorem at leo pretium commodo. Sed in urna...

SCSS

$headerHeightLarge : 100px;
$headerHeightSmall : 50px;

* {
    box-sizing: border-box;
}
body {
    float: left;
    margin: 0;
    height: 100%;
    width: 100%;
    overflow: hidden;
    >div{
        width: 100%;
        float: left;
        clear: both;
    }
}
ul, li {
    list-style: none;
    padding:0;
    margin:0;
}
#header {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100px;
    z-index: 10;
    background: red;
    color: white;
}
#notTheHeader{
    position: relative;
    float: left;
    width: 100%;
    margin-top: 100px;
    overflow-x: hidden;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch;
    &>.wrapper{
        position: relative;
        float: left;
        width: 100%;
        height: 100%;
    }
}
#pushDown {
    float: left;
    height: 100px;
    width: 100%;
    background: grey;
}
#magazineImage{
    height: auto;/*content is an image should keep ratio*/
    float: left;
    img{
        width: 100%;
    }
}
#content {
    overflow-x:hidden;
    overflow-y: auto;
    position: relative;
    padding-left: 200px;/*same as left rail width*/
    &.positioned {
        top: 100%;/*top set by js. 100% keeps it off screen till site renders so math can work*/
        left: 0;
        right: 0;
        height: 100%;/*height is set by js as well. if no push down/magazine we can do this with css*/
    }
    &.noScroll{
        #leftRail{
            position: absolute;
            top: 0;
            left: 0;
            bottom: 0;
        }
    }
    .wrapper{
        max-width: 800px;
    }
}
#leftRail {
    position: absolute;
    top: 0;
    left: 0;
    overflow-x:hidden;
    overflow-y: auto;
    margin-top: 20px;/*same as tab height - sass magic*/
    width: 200px;
    ul {
        width: 100%;
    }
    li {
        width: 100%;
        border-bottom: 1px solid gray;
        height: 40px;
        cursor:pointer;
        &:hover, .active{
            border-left:5px solid red;    
        }
  ...

JavaScript

//uses document because document will be topmost level in bubbling
$(document).on('touchmove',function(e){
  e.preventDefault();
});
//uses body because jquery on events are called off of the element they are
//added to, so bubbling would not work if we used document instead.
$('body').on('touchstart','.scrollable',function(e) {
  if (e.currentTarget.scrollTop === 0) {
    e.currentTarget.scrollTop = 1;
  } else if (e.currentTarget.scrollHeight === e.currentTarget.scrollTop + e.currentTarget.offsetHeight) {
    e.currentTarget.scrollTop -= 1;
  }
});
//prevents preventDefault from being called on document if it sees a scrollable div
$('body').on('touchmove','.scrollable',function(e) {
  e.stopPropagation();
});

var Time = {
    $window : $(window),
    $body : $("body"),
    $notHeader : $("#notTheHeader"),
    $content : $("#content"),
    $header : $("#header"),
    $leftRail : $("#leftRail"),
    sizes : {},
    mobileSafari : false,
    userAgent : window.navigator.userAgent,
    throttleSpeed: 100
}

//detect mobile safari
if (Time.userAgent.match(/iPad/i)) {
   Time.mobileSafari = "ipad";
}
if(Time.userAgent.match(/iPhone/i)) {
    Time.mobileSafari = "iphone";
}

//set sizes
Time.getSizes = function(init){
    if(init){
        Time.sizes.window = {}
        Time.sizes.window.width = Time.$window.width();
        Time.sizes.window.height = Time.$window.height();   
    }
    return Time.sizes;
}
Time.getSizes(true);

Time.scrollUpExccess = function(){
    //Time.$notHeader.get(0).scrollTop = Time.$notHeader.get(0).scrollHeight + 100;
    Time.$body.get(0).scrollTop = Time.$body.get(0).scrollHeight;
}

Time.sizeContent = _.throttle(function(){
    var contentHeight,
        headerHeight;
    
    headerHeight = Time.$header.outerHeight(true);
    contentHeight = Time.$window.height() - headerHeight;//ignore push down and mag image height
    
    
    if(Time.mobileSafari == "iphone"){
        //add padding to make up for mobile safari wackyness
       ...