Dynamic Bootstrap Affix Fix

arnarstef wrote this on Jun 17, 2014


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


Share this post


About the author

Arnar is a web developer and co-founder of bluthemes. Bluthemes creates WordPress themes and sells them exclusively on ThemeForest.net. Check out the theme portfolio right here.

Subscribe to our newsletter

If you're interested in Web development, WordPress or would like to hear about our journey as a ThemeForest author insert your email below and get our latest content first!

The latest theme from Bluthemes

Bacon

User Generated Recipe Theme

Bacon is the perfect food & recipe theme for you! It allows you to post recipes as well as open recipe submission up for your users.


Leave a comment