6th Oct 2016

How to Code a Fixed Navigation Bar for your Website

by: Lucile Peran

blog hero img

A few weeks ago, we were proud to annouce that our work on Three Sixty° Property Group website had been awarded a prestigious 'Site of the Day' website award by Awwwards.com!

Today I'm excited to share with you how to code a simple and useful fixed navigation as used on Three Sixty website, using HTML, CSS and jQuery.

 

 

Getting Started

The navigation bar will be fixed at the top of the page.
By default only the bottom section is visible (navbar is minimized). When scrolling back up, the top section shows up (navbar is maximized).

 

HTML

<div id="navbar" class="is-minimized">
<div class="top-section"></div>
<div class="bottom-section"></div>
</div>

 

CSS

#navbar { position: fixed; }

.top-section, .bottom-section { position: relative; }
.top-section { height: 70px }
.bottom-section { height: 50px; }

#navbar.is-maximized {transform: translateY(0);}
#navbar.is-minimized transform: translateY(- 70px ); /* top section height */

 

Triggering navbar states

When user scrolls, we want to miminize or maximize the navbar depending on the scroll direction.

Scroll event

For better performance we will check every 50ms if the user has scrolled instead of constantly listening to the window scroll event.

var didScroll, lastScrollTop = 0;
var navbar = $('#navbar');
function init() {

$(window).scroll(function(event){
didScroll = true; });

setInterval(function() {
if (didScroll) {
//handleScroll();
didScroll = false;
}
}, 50);

}

 

Handle scroll

Check if the user scrolled up or down.

function handleScroll() {
var st = $(window).scrollTop();
var navbar_height = navbar.outerHeight();
// Scroll Down: minimize navbar
if (st > lastScrollTop && st > navbar_height){
//minimize();
}
// Scroll Up: maximize navbar else if (st + $(window).height() < $(document).height()) { //maximize();
}
lastScrollTop = st;
}

 

Show/hide top section

We had a few issues on Safari: the navbar was jumping when css animations were constantly attached to it, so we prefered to use Javasscript to add our CSS transitions when needed and then remove them once done.

var duration = 300; // animaton speed

function minimize(){
// if navbar is maximized, add transition
if ( navbar.hasClass('is-maximized') ) {
transition();
}
// hide top menu
navbar.removeClass('is-maximized').addClass('is-minimized');
}
function maximize() {
// if navbar is minimized, add transition
if ( navbar.hasClass('is-minimized') ) {
transition();
}
// show top menu
navbar.removeClass('is-minimized').addClass('is-maximized');
}
function transition() {
// add css transition
navbar.css({
'-webkit-transform' : 'transform ' + duration +'ms',
'-moz-transform'    : 'transform ' + duration +'ms',
'-ms-transform'     : 'transform ' + duration +'ms', '-o-transform'      : 'transform ' + duration +'ms', 'transition'        : 'transform ' + duration +'ms'
});
// remove css transform when transition is done
setTimeout(function(){
 navbar.css('transition','none');
}, duration)
}

 

Optimization... we're almost there!

For better performance, we don't run any code if the navbar is transitioning. 

var duration = 300; // animaton speed 
var transitioning = false;

function transition() {

// add css transition
transitioning = true;
navbar.css({
'-webkit-transform' : 'transform ' + duration +'ms',
'-moz-transform'    : 'transform ' + duration +'ms',
'-ms-transform'     : 'transform ' + duration +'ms',
'-o-transform'      : 'transform ' + duration +'ms',
'transition'        : 'transform ' + duration +'ms'
});

// remove css transform when transition is done
setTimeout(function(){
 navbar.css('transition','none');
transitioning = false;
}, duration)
}

function handleScroll() {
var st = $(window).scrollTop();
var navbar_height = navbar.outerHeight();

// make sure navbar is not transitioning
if ( transitioning ) {
return;
}

// Scroll Down: minimize navbar
if (st > lastScrollTop && st > navbar_height){
minimize();
}

// Scroll Up: maximize navbar
else if (st + $(window).height() < $(document).height()) {
maximize();
}

lastScrollTop = st;
}

 

Finally, add a buffer

User must scroll at least 50px to toggle top section.

var buffer = 50;
function handleScroll() {
var st = $(window).scrollTop();
var navbar_height = navbar.outerHeight();

// make sure navbar is not transitioning and user has scrolled more than 50px
if ( transitioning || Math.abs(lastScrollTop - st) <= buffer ) {
return;
}

...
}

 

Conclusion

Voilà, that's all you need to create a dynamic fixed navigation bar!

Check out the live demo on Codepen and visit Three Sixty° Property Group website... Let us know what you think!

 

View Demo & Code

 

ABOUT THE AUTHOR

Lucile Peran

Front-End Developer at Liquid Agency