I know about the positioning of div (fixed, absolute and relative). I can attach a fixed div to body so that it will stick to the same position while scrolling body. Here I
It can be done by testing the scrollTop() against the heights of the containers.
var $sidebar = $("#sidebar"),
$window = $(window),
offset = $sidebar.offset(),
topPadding = 50,
calc= 0,
max = 0;
$window.scroll(function() {
calc = $window.scrollTop() + $sidebar.height() + offset.top;
if(calc > $('#main').height()) {
max = $('#main').height() - $sidebar.height();
$sidebar.stop().css('marginTop', max);
} else if ($window.scrollTop() > offset.top) {
$sidebar.stop().animate({
marginTop: $window.scrollTop() - offset.top
});
} else {
$sidebar.stop().animate({
marginTop: 0
});
}
});
#wrapper {
width: 100%;
}
#main, #more {
width:70%;
background-color: black;
color:white;
height: 900px;
float:left;
}
#more {
background-color: red;
}
p {
margin-top:50%;
}
#sidebar {
width:30%;
background-color: blue;
color:white;
height: 500px;
float:left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="wrapper">
<div id="main">
<p>Main Content</p>
</div>
<div id="sidebar">
<p>Sidebar</p>
</div>
<div id="more">
<p>More Content</p>
</div>
</div>
Taking the Facebook sidebar as an example it seems that as soon as the browser scrolls vertically to a certain threshold (the top of the screen hits the top of the final ad in the sidebar) it changes the class on the sidebar.
At this point it sets the css position to fixed and sets a top style on the sidebar of -???px so that it appears at that threshold has not moved but when you scroll down it will not scroll anymore.
You can detect the offset of a particular element using the jquery scrollTop() function. http://api.jquery.com/scrollTop/
Here you have three tutorials for the intended task (first results out of google with query: "fixed sidebar on scroll")
http://www.waypointarts.com/blog/2013/06/29/fixing-a-side-bar-while-scrolling-until-bottom
http://andrewhenderson.me/tutorial/jquery-sticky-sidebar/
http://css-tricks.com/scrollfollow-sidebar/
Here is the code for one of the approaches:
CSS
#page-wrap {
width: 600px;
margin: 15px auto;
position: relative;
}
#sidebar {
width: 190px;
position: fixed;
margin-left: 410px;
}
jQuery
$(function() {
var $sidebar = $("#sidebar"),
$window = $(window),
offset = $sidebar.offset(),
topPadding = 15;
$window.scroll(function() {
if ($window.scrollTop() > offset.top) {
$sidebar.stop().animate({
marginTop: $window.scrollTop() - offset.top + topPadding
});
} else {
$sidebar.stop().animate({
marginTop: 0
});
}
});
});
With absolute position (in fixed position we have to hide scroll and set scrollTop instead of top):
$(document).scroll( function() {
var offset = $(this).scrollTop() + $(window).height() - $('#sidebar').outerHeight();
$('#sidebar').css('top', Math.max(0, offset));
});
* {
margin: 0;
padding: 0;
}
#content {
height: 2000px;
padding-right: 40%;
background: red;
}
#sidebar {
height: 1000px;
position: absolute;
width: 40%;
top: 0; right: 0;
background: orange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="content"></div>
<div id="sidebar"></div>
fiddle
That is possible by placing your sidebar absolute and change that to fixed as soon as the windows scroll position passes the bottom.
The CSS:
#sidebar {
height: 120%;
width: 100px;
border: 2px solid blue;
padding: 20px;
margin: 20px;
position: absolute;
top: 0;
}
The jQuery:
$(document).ready(function() {
var bottomPos = $('#sidebar').outerHeight(true) - $(window).height();
$(window).scroll( function() {
if ( $(window).scrollTop() > bottomPos ) {
$('#sidebar').css({'position':'fixed','top':'auto','bottom':'0px'});
} else {
$('#sidebar').css({'position':'absolute','top':'0px'});
}
});
});
And a demo.