This course will extend what was learned in the HTML & CSS Basics series, venturing further into modern best-practices in HTML and CSS and introducing basic javascript.
Front-end Series →
Update: June 2021
Lots of people keep finding this page through search and the original method from 2014 was outdated and broken.
So, this new method (embedded below and also available on CodePen) is a better version that works with vanilla JS instead of requiring jQuery. To see it in action on a full page, check out my “about” page and look for the sticky menu on the left.
I slightly modified the original by Danilo Bilanoski to use getBoundingClientRect().top
instead of the original offsetTop
in order to be able to use the sections inside of a relatively positioned parent. For a discussion of that, see this article.
Hope this helps!
See the Pen FORK: Highlight Active Nav Link On Page Scroll (Plain JS) by Alex Turnwall (@alturnwall) on CodePen.
.
.
.
Original post below (do not use—deprecated)!
The original method (below) is from 2014, outdated, and broken! I recommend you use the JS method above instead!
Adding “scrolling” navigation to your website can be helpful in a bunch of different scenarios. This tutorial show you how to use some popular jQuery plugins to easily add flexible nav options to your site.
You can preview how this looks in the demo (opens in new tab).
You’ll need to download a separate plugin file and include it on your site for this to work. I should note that I am not the author of this—I simply combined four existing jQuery plugins into one file for ease of inclusion. The popular “ScrollTo” plugin from Ariel Flesler provides the base functionality, while (a now dated version of) One Page Nav by Trevor Davis provides the navigation “current” state that updates as you click or scroll. You can download the combined file here:
Download CombinedScroll Package
Let’s find out how to get this up and running on our own site.
Set up the HTML
Step 1
The purpose of adding “scrolling” navigation is to quickly jump to different sections of your page. So first, we have to add some content so that our page is long enough to scroll to different sections. I’ve built on top of the code that you should have had after the previous tutorial, adding five separate sections on the page, which you can see in a new tab here →.
You can add whatever content you’d like, but the important thing is for each section to have a unique ID that will serve as the “anchor” for the anchor links in our navigation, and for the sections to be vertically long enough that we can scroll in between them.
In your HTML, you should have different sections that have unique ID’s like this:
<div id="section-one"> <!-- Content Here --> </div> <div id="section-two"> <!-- Content Here --> </div> <!-- ... repeat as needed. -->
If you look at my specific code in the demo, my sections look like this:
<div id="section-one" class="gd-section pad-large"> <!-- Content Here --> </div>
I’m using the existing <div> elements on my page that I set up in my grid. They already have classes that give them visual “layouts”—here, I’m simply adding unique IDs as identifiers for the anchor links.
In the demo, I have five unique sections on my page, each with a unique ID.
Step 2
I also added an empty <div> at the very top of the page—right below the opening <body> tag—with an ID of “top”. This will be used to return us to the “top” of the page.
<body> <div id="top"></div>
On any site where I’m utilizing scrolling nav—or simply want to give people an option to get back to the top after a long page of content, I’ll add this “hidden” <div> immediately under the opening <body> tag, so I know I’m always being taken to the top-most position on the page.
Step 3
Okay, so now we have our long page of content totally set up, and now we need navigation to get us from section to section. This is achieved simply using only HTML and CSS—no javascript required. All we need to do is make a “fixed” navigation section that uses anchor links to jump us to different parts of the page.
Note: If you need a refresher on anchor links—check out the anchor link section of my tutorial about ID vs. Class (opens in new tab).
I’m going to use the navigation that we built in Tutorial 6: Building a CSS dropdown menu as a base, so I have some styles and structure to start with. But, I’m going to add another class “page-navigation ” to the <nav> element here, so I can override the existing styles where necessary. I’ll place this around the top of the page—below my other site-wide navigation.
<nav class="site-navigation page-navigation"> <ul class="menu"> <li><a href="#top">Top</a></li> <li><a href="#section-one">One</a></li> <li><a href="#section-two">Two</a></li> <li><a href="#section-three">Three</a></li> <li><a href="#section-four">Four</a></li> <li><a href="#section-five">Five</a></li> </ul> </nav>
Step 4
And since the point of the menu is to be visible while scrolling throughout the page, we need it to be “fixed”, or “sticky”, so that it’s always visible. We’ll use some simple CSS for this:
nav.page-navigation { width: 80px; background-color: #ebebeb; position: fixed; top:10%; left:0; } nav.page-navigation li { width: 100%; } nav.page-navigation a { padding: 0.6em 10%; width: 80%; }
At this point, the page should look how we want it to (fixed to the side of the page as we scroll), and the anchor links in the navigation should actually “jump” us to the correct section of the page, as seen in this demo page. They won’t “scroll” yet, but they will “jump”.
Important: make sure your navigation anchor links are actually moving the page now!
The rest of the tutorial uses javascript to make the page appear to “scroll” between sections, but the base functionality of the anchor links needs to work properly before you add the javascript.
I like these particular javascript plugins to achieve this functionality because they are progressively enhancing the page. If for some reason the user doesn’t have javascript turned on, or the files don’t load properly, the navigation will still work—you just won’t have the scrolling motion.
After that’s working, let’s move on to making it scroll.
Adding the scroll with javascript plugins
Step 5
First, include file you downloaded at the start of the tutorial in your site’s folder.
(Download CombinedScroll Package)
If you’ve been following the series from the start, we’ve been using HTML 5 Boilerplate, and that is the code package that is running with the demo. If you’re in that boat, then put the “jquery.combinedScroll.js” file inside the “js” folder within Boilerplate.
Make note of where you placed the file, so you can create a link to it from your HTML page:
Step 6
On your HTML page below wherever you include jQuery, add a new line to include the file you just downloaded and added to your project folder.
If you’re following the Boilerplate example, then your code should look like the last (highlighted) line below. (Shown with other script links in the HTML file for reference.)
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script>window.jQuery || document.write('<script src="js/vendor/jquery-1.10.2.min.js"><\/script>')</script> <script src="js/plugins.js"></script> <script src="js/main.js"></script> <script src="js/jquery.combinedScroll.js"></script>
It’s important that this file is included below jQuery itself, because the plugins we’re including are dependent on jQuery to function. So, the jQuery code needs to process before our plugin code.
Step 7
After you have the Combined Scroll file linked, we need to add a quick jQuery hook to our page so that the OnePageNav plugin (part of the combined file) knows to use the “page-navigation” nav element as the target navigation for the scroll.
So, somewhere within the jQuery(document).ready function , add the following code to hook the One Page Nav plugin to the page-navigation element we created in step 3:
<script type="text/javascript"> jQuery(document).ready(function($) { // Hook up the current state to the nav bar $('.page-navigation').onePageNav(); }); </script>
Note that the selector .page-navigation is the class we added to the navigation element. Thanks to some smart plugin code from OnePageNav, that’s all we need to do to get this set up.
So go ahead an test your code out—clicking on any of the links in the fixed navigation section should scroll you to the corresponding section.
The last part to making this menu work is adding a “current” state to the menu styles, so that we know which section we’re looking at based on the menu.
Step 8
On your working page, click on any of the links in your navigation (other than top) and then inspect that element in your browser.

If you compare the link for the section you’re on to the other links in the navigation element, you should notice that the DOM had been updated with a new class added to the parent <li> . For example, if I clicked on “Three”, the code should now look like the below code in my element inspector tool (note, you’re NOT changing this in your code—it’s just what the code looks like in the inspector tool!)
<li><a href="#top">Top</a></li> <li><a href="#section-one">One</a></li> <li><a href="#section-two">Two</a></li> <li class="current"><a href="#section-three">Three</a></li> <li><a href="#section-four">Four</a></li> <li><a href="#section-five">Five</a></li>
The parent <li> of the section we’re on should now have a class=”current” attribute. The OnePageNav plugin adds this code to the nav element based on what section of the page is currently displayed in the browser window.
Cool. Now we know what the plugin is doing to the page, so we can use the output to style the navigation links.
Step 9
Let’s add a style to the CSS using the “current” class the the plugin outputs, ensuring that it’s under the default style for nav.page-navigation a:
nav.page-navigation .current a { background-color: #d2d2d2; color: #fff; }
Make sure you refresh your page in the browser to see the changes, but now, whether you click on the nav links to scroll the page up and down, or you just scroll the page up and down, the “current” style in the navigation bar should update according to which part of the page you’re on.
At this point, your file should work like the final demo (opens in new tab).
That’s all for now.
I’ll add configuration options and some more features soon.
How can we remove the dottled black line around the menu item we clicked on that appears after scrolling to another section?
hey,
i did every step, and its not working, i guess its just not linked as it should be,
can you help me with that pls?
Untitled Document
and before the body end i pasted this:
jQuery(document).ready(function($) {
// Hook up the current state to the nav bar
$(‘.page-navigation’).onePageNav();
});
i have a single link to another page can i use this code. i need this effect and also the different page navigation.
Thanks for this.
Can this be modified to allow for a unique background colour (change) for each nav item? I would like to coordinate the highlight with each of the page sections (background colour).
Thanks for this. I have this working (well) in my page – but is it possible to generate a different hilite colour for each menu item (to match a section background colour)?
External links in the same div no longer work after apply the onepagenav() method.
My website is only ‘mostly’ one-page.
Any thoughts?
i really dig this site.
good tutorial too.
i had the same problem with the page not scrolling.
i think they messed it up a little bit.
however i did not work with any of the pages or tutorials 1 through 10.
but i was able to parse and figure it out.
they key is to add a local scroll function to your page.
it is in the source. if you can’t find it it looks like this
”””””$.localScroll({ duration:500, });”””””’
Fantastic walk through! I really appreciate you putting this together.
I had a small problem where the nav links became underlined after applying the scripts. In case anyone else encounters it, it can be fixed by targeting the navigation in CSS and setting text-decoration: none.
For my class names it worked out to: .menu a{ text-decoration: none}
In my case page content is not showing appropriate with menu. Even when I clicked on page 2, it will show page 2 content but the selected menu will be “page 3 menu”. Any suggestion?
For External link fix: add filter: ‘:not(.external)’, and use class=”external” at lmenu list items.
$(‘.main-nav’).onePageNav({
currentClass: ‘active’,
changeHash: false,
scrollSpeed: 750,
scrollOffset: 61,
filter: ‘:not(.external)’,
easing: ‘swing’,
});
$(‘.navbar-brand’).onePageNav({
changeHash: false,
scrollSpeed: 750,
scrollOffset: 61,
filter: ‘:not(.external)’,
easing: ‘swing’,
});
Thank you SO SO MUCH!
I’ve been trying tutorials for days and couldn’t work it out.
Now it finally works.
Hello. How can I change the fixed green color in the menu? In CSS I can only select the color that will change on hover. I want to get rid of the green color completely…
Can you also provide the code for responsive menu like if the menu appears horizontally with nowrap scroll… If page scroll to hidden target menu it should slide the menu upto the menu item name that was hidden