I managed to make it work in my app, it is a matter of making the bottom styling consistent with the bottom passed to the affix call. If your footer have fixed height and the nearest positioned parent is the body, then it is matter of passing the same value for both. That works well enough for the Bootstrap 2.3's docs as seen here and here.
--
Now assuming you do not have a fixed height footer:
Step 1: Nearest positioned parent (offset parent)
First of all, we use absolute positioning to stick it to the bottom, but since your nearest positioned parent will be the body (that includes your footer) you don't have a fixed value for the bottom. To fix that we have to make a new positioned parent that encloses everything but the footer (important: header will probably be outside too). Set position: relative;
to either the top .container
or one of its ancestors (important: footer must be after this element).
Step 2: Footer height
Now, your bottom is relative to its container instead of body, but the bottom value of affix (used to know when to stick the affix to the bottom) is still relative to the end of the body, so you have to pass it a function that calculate the height of the elements after the container, if it is only the footer then this suffice: $('footer').outerHeight(true)
.
Step 3: Troubleshooting
Now, you have it all correct, but three things may still cause incorrect stick position and crazy flashing:
Other visual elements besides the footer that you didn't take into account, like second footers or that are not always showing, like the useful rails-footnotes gem;
Browser extensions that append elements to the DOM, if they are hidden or not in the flow then you shouldn't count their height, the easier way to get around that is to count only the elements your app know, but then an extension could end up breaking your app. You could test if an extension is causing you problems by using a browser or configuration that you don't have extensions installed, or just by going to "porn mode" (Incognito on Chromium (Ctrl+Shift+n), Private Browsing on Firefox (Ctrl+Shift+p)) if you haven't enabled extensions on it.
Javascript libraries also append elements to the DOM, you should not count their height as well.
To solve these you could try to make it work with the whole word (CoffeeScript with Underscore.js):
_($('footer').nextAll(':visible').addBack())
.filter((el) -> el.offsetParent?)
.reduce(((memo, el) -> memo + $(el).outerHeight(true)), 0)
Same thing, with Javascript and jQuery.fn.each:
var sum = 0
$('footer').nextAll(':visible').each(function() {
this.offsetParent != null && sum += $(this).outerHeight(true)
}
return sum
Or you could account only for the elements you know (I prefer this, the other one I coded for the challenge):
$('footer').outerHeight(true) + ($('#footnotes_debug').outerHeight(true) || 0)