An easy way to set up Bootstrap Affix (Sticky element)
I've spent a lot of time trying to find a quick jQuery snippet to slap in my code to get the Bootstrap Affix-Bottom working dynamically right off the bat, but I have never come a cross it, so what do we do when we can't find what we are looking for? We do it ourselves (and then blog about it I guess).
I'm not going to waste your time with a lengthy introduction about my developer-life so let's get right to it.
The Problem
As a theme developer we need to have our elements dynamic so we can count for changes our customers make themselves, there are of course infinite possibilities to how their website might look so we need to build our features with that in mind.
Let's just affix an element right up, with no stylings or nothing:
Using the default data-spy="affix" data-offset-top="60" data-offset-bottom="200"
on the right element.
That's not working so well, granted the correct pixels haven't been set, but nonetheless it can be a pain when elements are subject to change. It sticks to the bottom because it's exactly 200 but then it flips out. Sometimes it will flash in and out and flicker like crazy because it's calculating things the wrong way.
The Solution
I made a jQuery snippet so all you have to do is insert it into your javascript file, change the names of the first two elements and it should snap correctly. I calculate the height in jQuery so you don't have to make the top fixed, as well as the bottom. Check it out:
$(function(){ // name your elements here var stickyElement = '.stickyel', // the element you want to make sticky bottomElement = '.fakefooter'; // the bottom element where you want the sticky element to stop (usually the footer) // make sure the element exists on the page before trying to initalize if($( stickyElement ).length){ $( stickyElement ).each(function(){ // let's save some messy code in clean variables // when should we start affixing? (the amount of pixels to the top from the element) var fromTop = $( this ).offset().top, // where is the bottom of the element? fromBottom = $( document ).height()-($( this ).offset().top + $( this ).outerHeight()), // where should we stop? (the amount of pixels from the top where the bottom element is) // also add the outer height mismatch to the height of the element to account for padding and borders stopOn = $( document ).height()-( $( bottomElement ).offset().top)+($( this ).outerHeight() - $( this ).height()); // if the element doesn't need to get sticky, then skip it so it won't mess up your layout if( (fromBottom-stopOn) > 200 ){ // let's put a sticky width on the element and assign it to the top $( this ).css('width', $( this ).width()).css('top', 0).css('position', ''); // assign the affix to the element $( this ).affix({ offset: { // make it stick where the top pixel of the element is top: fromTop, // make it stop where the top pixel of the bottom element is bottom: stopOn } // when the affix get's called then make sure the position is the default (fixed) and it's at the top }).on('affix.bs.affix', function(){ $( this ).css('top', 0).css('position', ''); }); } // trigger the scroll event so it always activates $( window ).trigger('scroll'); }); } });
If the element spacing around the element is smaller than the element, then we won't apply the affix on it and it'll appear as a regular relative element, otherwise we calculate the offset from the top and apply it on the top
option in the affix. Dynamic!
The Result
The result is a fully calculated affix ready for deployment, we use this constantly and it has yet to cause issues, if you run into any I would love to hear them in the comments below