JSFiddle - React, Tailwind, and code Playground
by wrxsti85
HTML
<script src="//code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<link rel="stylesheet" href="//stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
<script src="//stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<nav></nav>
<div class="container">
<div class="row">
<div class="col col-3">
<div id="sidebar">Sidebar</div>
</div>
<div class="col col-9">
<div class="content">Content</div>
</div>
</div>
</div>
<footer></footer>
CSS
.row {
margin-top: 20px;
}
#sidebar, .content {
border: solid 1px #6c757d;
padding: 10px;
background: #f8f9fa;
}
#sidebar {
height: 1000px;
width: 255px;
}
.content {
height: 2000px;
margin-bottom: 50px;
}
nav, footer {
height: 600px;
background: #f8f9fa;
border: solid 1px #6c757d;
}
nav {
margin-bottom: 50px;
}
.position-fixed {
position: fixed;
}
.position-relative {
position: relative;
}
.anim {
-webkit-transition: all .4s;
-moz-transition: all .4s;
-ms-transition: all .4s;
-o-transition: all .4s;
transition: all .4s;
}
JavaScript
var lastScroll = 0,
lastScrollDirection = true; // scrollingdown
$(window).on('scroll', function(){
var topAnchorPad = 50,
topAnchor = $('nav').offset().top + $('nav').outerHeight(true),
bottomAnchorPad = 50,
bottomAnchor = $('footer').offset().top,
sidebar = $('#sidebar'),
sidebarHeight = sidebar.outerHeight(false),
sidebarTop = sidebar.offset().top,
sidebarBottom = sidebarTop + sidebarHeight,
scrollTop = $(window).scrollTop(),
windowHeight = window.innerHeight,
docHeight = $(document).height(),
isAtTop = (scrollTop <= topAnchor - (topAnchorPad / 2)),
isAtBottom = (scrollTop + sidebarHeight >= bottomAnchor - bottomAnchorPad),
scrollingDown = lastScroll < scrollTop,
isShortSidebar = sidebarHeight < windowHeight,
directionChanged = scrollingDown != lastScrollDirection,
hasCollapsingNav = false;
console.log(scrollTop, sidebarTop)
if (isAtTop)
{
sidebar
.removeClass('position-fixed')
.addClass('position-relative')
.css({
'top': '0px'
});
}
else if (isAtBottom)
{
sidebar
.removeClass('position-fixed')
.addClass('position-relative')
.removeAttr('style')
.css({
'top': (bottomAnchor - topAnchor - sidebarHeight - topAnchorPad)
});
}
else if (isShortSidebar)
{
sidebar
.removeClass('position-relative')
.addClass('position-fixed')
.removeAttr('style')
.css({
'top': topAnchorPad / 2
});
}
else
{
if (scrollingDown && scrollTop >= sidebarHeight - (bottomAnchorPad / 2) ) // snap to bottom
{
console.log('bottom sticky!')
sidebar
.removeClass('position-relative')
...