I've seen different implementations of this. The most popular solution is a "chaser" where the element's absolute position is updated dynamically after each page scroll event. You have probably seen sites like this. They are a bit annoying and clunky - the element is constantly hiding and showing after every scroll.
After no luck finding a solution that I liked, I created one. It is below for your enjoyment. It uses jQuery to make things easier (ie, this framework is required). Take, use and be merry.
AND, the javascript:
$(function() { window.floater = {}; /* Settings */ window.floater.element = $('#float'); // Element to float window.floater.topMargin = 20; // Margin from top of window /* Global Vars & Initial Position */ window.floater.captured = false; window.floater.posi = window.floater.element.offset(); window.floater.marginLeft = parseInt(window.floater.element.css('margin-left').replace('px', ''), 10); $(window).scroll(function() { var curScroll = { top: $(window).scrollTop(), left: $(window).scrollLeft() }; if (curScroll.top >= (window.floater.posi.top - window.floater.topMargin)) { if (!window.floater.captured) { window.floater.captured = true; var scrollAtTrigger = curScroll.top; if ((window.floater.posi.top - scrollAtTrigger) < window.floater.topMargin) scrollAtTrigger = window.floater.posi.top - window.floater.topMargin; } window.floater.element .css({ position: 'fixed', top: (window.floater.posi.top - scrollAtTrigger)+'px', left: (window.floater.posi.left - window.floater.marginLeft - curScroll.left)+'px' }); } else { window.floater.captured = false; window.floater.element.css({ position: 'static' }); } }); $(window).resize(function() { var posiFix = window.floater.element.css({position: 'static'}).offset(); window.floater.element.css({position: 'fixed'}); window.floater.posi.left = posiFix.left; $(window).scroll(); }); });
The nuts and bolts: Put the float wherever you'd like it to be on the page initially. Then, when the document is loaded, the JavaScript goes to work. It sets up two events: one page-scroll event and one page-resize event. This is where the hard work is done. Once the page scrolls past a certain point, the position of the floater is set to fixed which means it remains a certain position relative to the window or viewport. There is no flickering or chasing using this method. It is clean and smooth.
Note: The floater's initial CSS position must be set as 'static' (which is a CSS default if it is undeclared). If you need to set it to 'relative' or 'absolute', use a wrapper to position it.
Note 2: I've noticed on Firefox 6.0 that there is a weird bug (?) that causes iframes to refresh if their positioning switches from 'static' to 'fixed'. So, if you plan on playing a YouTube video in your floater, beware: it my refresh and reset your video on scroll.