Sticky Sidebar

Sticky Sidebar with short or long sidebar content

by Dhruvang Gajjar

HTML

<div id="header">
  <h2>Header</h2>
  <p>This is the header</p>
</div>

<div id="sidebarWrap">
  <div id="sidebar">
    <h2>Sidebar</h2>
    <p>Sidebar has content in ifgjffkykkkdftk5tjkk5rtujjerycbnedjdrjhrjtjthotitujtjigyujt5jhsdmkfjhgjhrjfdjir;t and will be sticky until it's bottom container reaches the footer container. Then it will scroll up as expected. Oh YEAH</p>
  </div>
</div>

<div id="content">
  <h2>Content</h2>
  <p>This is the main content section.</p>
</div>

<div id="footer">
  <h2>Footer</h2>
  <p>This is the footer</p>
</div>

CSS

body {
  margin: 10px auto;
  font-family: sans-serif;
  width: 800px;
}

div {
  border-radius: 5px;
  box-shadow: 1px 2px 5px rgba(0, 0, 0, 0.3);
  border: 1px solid #ccc;
  padding: 5px;
}

#sidebarWrap {
  height: auto;
  width: 210px;
  float: right;
  position: relative;
  box-shadow: none;
  border: none;
  margin: 0;
  padding: 0;
}

#content {
  width: 568px;
  height: 800px;
}

#footer {
  clear: both;
  margin: 10px 0;
}

#sidebar {
  width: 200px;
  height: 300px;
  position: absolute;
}

#header {
  height: 80px;
  margin-bottom: 10px;
}

#sidebar.fixed {
  position: fixed;
  top: 0;
}

#footer {
  height: 800px;
}

JavaScript

$(function() {
  var top = $('#sidebar').offset().top - parseFloat($('#sidebar').css('marginTop').replace(/auto/, 0));
  var footTop = $('#footer').offset().top - parseFloat($('#footer').css('marginTop').replace(/auto/, 0));

  var maxY = footTop - $('#sidebar').outerHeight();

  $(window).scroll(function(evt) {
    var y = $(this).scrollTop();
    if (y > top) {
      if (y < maxY) {
        $('#sidebar').addClass('fixed').removeAttr('style');
      } else {
        $('#sidebar').removeClass('fixed').css({
          position: 'absolute',
          top: (maxY - top) + 'px'
        });
      }
    } else {
      $('#sidebar').removeClass('fixed');
    }
  });
});