Fixed Floating Elements
Posted on 23rd October 2009 — On visiting Apple’s web site an putting items in my shopping basket, I noticed (an old effect) where the shopping basket would follow me down the page. We’ll look at how to replicate the fixed floating sidebars or elements with very little jQuery.

Watch
Watch jQuery Fixed Floating Elements screencast (Alternative flash version)
QuickTime version is approximately 45Mb, flash version is streaming.
View the demo used in the screencast
Understanding the effect
When I scrolled down the Apple store when I had something in my basket I found that the summary and what I had selected would follow me down the page. I’ve seen this effect before, but often it would be a little jumpy and the element would have to catch up with the scrolling.
Apple’s version was very smooth and didn’t jump when I kept scrolling.
Upon firing up Firebug I can see that once the scrollbar gets to the point where the basket is at the top of the page, the basket has a class applied to it which gives it a
position: fixed– which explains why it holds still while I continue to scroll down.Other ways to do it
Like I said, I’ve seen this effect before, for example on Simon Willison’s web site (see the comments form) (one of the speakers for my Full Frontal conference).
When I scroll down the page, the comments form can sometimes “play catchup” with the scrolling position, because I suspect the top position is being recalculated (though I’ve not checked his code to be sure or not).
So I’ve taken the style of Simon’s site for the example and added the jQuery we need to make this a nice smooth effect.
Caveat: IE6
Since we’re solving this effect using
position: fixed, IE6 doesn’t support this CSS property. I’m not saying that IE6 doesn’t matter, but I’m suggesting that this effect isn’t a requirement to be able to interact with the site properly, so if IE6 users don’t see this extra effect, I’m okay with this. As I explained in the screencast, you’ll need to decide this yourself, check your site’s demographic, whether it’s a personal project, etc.Markup & CSS
The trick really happens in the CSS here and being able to flip back and forth between absolute positioning and fixed positioning. So I’ve prepared the layout as such. You guys and gals being designer and front-end types will know how you’ll want to style the elements.
One trick I did find was that I had to wrap the element that would receive
position: fixedin a wrapper withposition: absoluteso that the left position was again the wrapper rather than thebodyelement. The effect of not having the wrapper, meant that when I switched fixed on the element, it jumped to the left by the amount of padding and margin set on the body element.I’ve simplified the markup form the live example
jQuery
The jQuery required is very simple to create this effect. Obviously first up, include jQuery:
First of all, we need to capture the initial position of the comments form. There’s a few parts to this to ensure we get a real number (rather than
NaN– not a number), and to ensure we also calculate in themargin-top:Next we subtract the
margin-top(I’ve usedmarginTopin the code below, but they’re interchangeable) of our element:However, the result from the CSS method is “20px”, so we need this as a number so we can subtract properly, we’ll use
parseFloatto achieve this:Finally, if we don’t include a margin in the CSS, the result of the CSS method call is
auto, which won’t parse properly, so we need to replace the text “auto” with the number 0:This all needs to be done inside once the document has loaded, so we’ll wrap all of this in the
readymethod, and while we’re at it we need to bind an event handle when the user scrolls down the page, so we’ll attach this when the page has loaded:Within the scroll event handler, we need to:
$(window).scrollTop()fixedclassNote that since we bind the scroll event to the
windowobject, I’ve used$(this).scrollTop()(sincethisis also thewindowin this case).All of this put together results in:
And that’s how to create a fixed floating element or sidebar and make it super smooth when you scroll.
There is some optimisation you could do to this code, but for a simple effect this should work nicely for you.
You should follow me on Twitter here I tweet about jQuery amongst the usual tweet-splurges!