Content that scrolls with the browser window is not a new concept. We all know how to position things relative to the browser window with position: fixed; However what if we only wanted it to stick the browser window conditionally? Most of the time I see this in practice, the developer has used Javascript to reposition the container absolutely so it always appears within the constraints of the users current window position. The problem with this method is that it causes the stickied content to jitter as it slides down (or up) the page. This can be extremely irritating to the end user. Let’s see an example of the incorrect method.
In order to smooth, rather than re-positioning this sticky content every time the user scrolls, we can change the positioning type from relative or absolute to fixed. This will fix the content to the browser window and allow it to scroll smoothly. Essentially what we are doing is changing the CSS once whenever the user scrolls far enough down the page to need the desired effect rather than changing the CSS every time the user scrolls. Let’s see an example of the proper method.
Here’s how to do it.
First the CSS: position the sticky content to its original location
#sticky {
position: relative;
height: 600px;
width: 300px;
}
Building the Javascript.
I am using jQuery to make it faster and easier to build, since we include jQuery on pretty much everything we build. Doing it this way will make a lighter footprint than building it in straight javascript. Therefore we will need to invoke jQuery - we tend to use Google AJAX Libraries for this.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>
First set the parameters for the sticky: We need to know how high the sticky will be; if it is higher than the user’s browser window then we cannot scroll it because they would never see the bottom content. Next we need to know if there is any padding necessary at the top and bottom of the element when it is stickied. Finally we need our offset from the top and the height of any footer elements that we do not want to cover up.
var $stickyHeight = 600; var $padding = 10; var $topOffset = 200; var $footerHeight = 83;
Now lets set up a framework for the rest of the javascript. We will build a function to handle the lifting and then invoke it using jQuery’s $(window).scroll() function
function scrollSticky(){
}
$(window).scroll(function(){
scrollSticky()
});
Now we need to set up the conditional logic to determine which of the three states the sticky should be in (bottom position, sticky or top position). This is all wrapped in a conditional statement to test to see if the users browser window is tall enough to support the sticky.
function scrollSticky(){
if($(window).height() >= $stickyHeight) {
if($(document).height() - $footerHeight - $padding < $(window).scrollTop() + $stickyHeight) {
}else if($(window).scrollTop() + $padding > $topOffset) {
}else{
}
}
}
Finally we are ready to manipulate the CSS of the document so the sticky is positioned correctly for each of the 3 states.
function scrollSticky(){
if($(window).height() >= $stickyHeight) {
var aOffset = $('#sticky').offset();
if($(document).height() - $footerHeight - $padding < $(window).scrollTop() + $stickyHeight) {
var $top = $(document).height() - $stickyHeight - $footerHeight - $padding;
$('#sticky').attr('style', 'position:absolute; top:'+$top+'px;');
}else if($(window).scrollTop() + $padding > $topOffset) {
$('#sticky').attr('style', 'position:fixed; top:'+$padding+'px;');
}else{
$('#sticky').attr('style', 'position:relative;');
}
}
}
Lets see it all together.
<script>
var $stickyHeight = 600;
var $padding = 10;
var $topOffset = 200;
var $footerHeight = 83;
function scrollSticky(){
if($(window).height() >= $stickyHeight) {
var aOffset = $('#sticky').offset();
if($(document).height() - $footerHeight - $padding < $(window).scrollTop() + $stickyHeight) {
var $top = $(document).height() - $stickyHeight - $footerHeight - $padding;
$('#sticky').attr('style', 'position:absolute; top:'+$top+'px;');
}else if($(window).scrollTop() + $padding > $topOffset) {
$('#sticky').attr('style', 'position:fixed; top:'+$padding+'px;');
}else{
$('#sticky').attr('style', 'position:relative;');
}
}
}
$(window).scroll(function(){
scrollSticky()
});
</script>
Tags: Content, Javascript, jQuery, Sticky, Tutorial





Thanks for the walkthrough, I’ve been looking for this for a while.
I made a slight change in the code, to make it work better for me:
var $stickyDiv = $(”.etest_builder-recap”);
var $stickyHeight = 600;
var $padding = 10;
var $topOffset = 200;
var $footerHeight = 83;
$(window).scroll(function(){
if($(window).height() >= $stickyHeight) {
var aOffset = $stickyDiv.offset();
if($(document).height() - $footerHeight - $padding $topOffset) {
$stickyDiv.attr(”style”, “position:fixed; top:”+$padding+”px;”);
}else{
$stickyDiv.attr(”style”, “position:relative;”);
}
}
});
Thanks again.
@Gabriel no problem. Looks like you’ve simplified it a bit and removed the footer limit. I should have thought of moving the div name itself to a variable like that. Makes more sense for the demo than having it in the code.
Nice to see it was useful, I’d love to see the finished product.
Hmmm, nothing scrolls on both examples on FF 3.6
Seems to be working fine in Firefox 3.6 for me.
The Javascript has a conditional statement in it that monitors the height of your browser window. If your browser window is not high enough to view the entire content of the scrolling area it will not scroll (so users with small browser windows can still see all the content). You could be experiencing this if you are not seeing it scroll.
To remove this section of the javascript remove the line:
if($(window).height() >= $stickyHeight) {
and of course its corresponding closing brace.
Working fine now
Thanks