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

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

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: fixed in a wrapper with position: absolute so that the left position was again the wrapper rather than the body element. 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.

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 the margin-top:

var top = $('#comment').offset().top;

Next we subtract the margin-top (I’ve used marginTop in the code below, but they’re interchangeable) of our element:

This all needs to be done inside once the document has loaded, so we’ll wrap all of this in the ready method, 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: