Making a scroll-dependent menu bar with CSS3 and JavaScript

Making your menu bar fix to the top of the page is something that’s been done a lot. However what if you don’t want to start your menu out as being fixed to the top? And how do you make your menu look different from its original state when you make it fix to the top of the screen?

We’ll look into all these things and create a nice scroll-dependent menu bar with CSS3 and JavaScript this way that certainly does improve the user experience for your visitors.

The demo and source code are available below, so have a look!

Since the source code is all clearly available in the demo, let’s go over the important parts.

I decided to use the magnificent JavaScript library scrollMonitor. This library exposes a few events which will allow you to monitor wether an element leaves or enters the viewport.

Setting the basic CSS and defining a CSS3 animation

First, let’s look at some of the specific CSS for this example.

nav#menu ul li {
  float: left;
  padding: 0 20px;
  background: #3498db;
  list-style: none;
  margin-right: 5px;
  line-height: 50px;
  height: 50px;

   * This element will get an alternative style
   * once we apply the "scrolled" class.
   * We also want a nice animation so we can
   * simply set CSS3 transitions for this.
  transition: margin 0.1s ease-in-out;

nav#menu ul li:nth-child(1) {
  margin-left: 5px;

As you can see, aside from some general styling, I added a margin of 5px to the right of every li (and to the left of the last one). I want this margin to disappear when I position the menu to the top of the page, so I added a transition to the margin. This specifies that we will animate to the new margin over 0.1 seconds.

Next, let’s also add a sitename that only appears when you scroll down and pin the menu to the top. This is handy if you have a logo or sitename that usually appears above your menu somewhere, but you want it to stay visible to the user next to the navigation when someone scrolls down. This is what Google+ also does!

The opacity will be set to 0 by default since we only want it to be visible when the user has scrolled down.

nav#menu h1#sitename {
  font-size: 1.2em;
  line-height: 50px;
  margin: 0;
  position: absolute;
  left: 0.5em;
  color: white;
  opacity: 0;

   * Same thing here as with the menu items.
   * This element will be animated into its
   * alt. state with the transition property
  transition: opacity 0.1s ease-in-out;

Styling the class for the fixed menu

Now, let’s define a class which we will use to define our alternate style for when the user scrolls down and the menu pins to the top. I chose to simply name this class “scrolled”.

 * Once the 'scrolled' class is toggled 
 * we can set any alternative styling that we
 * want for the menu bar 

nav#menu.scrolled {
  margin: 0;
  position: fixed;
  top: 0;

nav#menu.scrolled ul li {
  margin: 0;

nav#menu.scrolled h1#sitename {
  opacity: 1;

As you can see this is really simple. We removed the margin from the menu and menu items. We also set the position property to fixed and top top 0. Lastly we make the sitename visible.

Now we are almost good to go!

Detecting when the menu bar leaves the page

For this, I decided to go with the stateChange method of scrollMonitor. We can then use isAboveViewport and jQuery’s toggleClass function to toggle the scrolled class on the menu according to menu leaving or entering the viewport. When it leaves, we add the class so that it fixes to the top of the screen. If it enters again, we remove the class.

// Store the menu in a variable to make life easier.
var menu = $('nav#menu');

// Create a new watcher to monitor the menu leaving/entering the screen.
var watcher = scrollMonitor.create( menu );

// Lock the watcher

// The best part: toggle the "scrolled" class on/off when the menu leaves/enters
watcher.stateChange(function() {
  $(menu).toggleClass('scrolled', this.isAboveViewport)

As you can see it’s really short and simple!

That’s all!

That’s all there is to it! I hope you liked this example. It can greatly increase your user experience. The knowledge gained is applicable to more than just a menu bar, too! You could for example create a button to scroll back to the top of the page and much more.

Share the knowledge!
Share on Facebook0Tweet about this on Twitter0Share on Google+0Share on StumbleUpon0Share on Reddit3Share on LinkedIn0Share on TumblrBuffer this pageDigg this


You may also like...

Stay updated