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.
