Like our free content? Then you'll love our exclusive Club!
Divi Academy Membership gives you exclusive access to over 110 resources, including child themes, layouts, cheatsheets, tutorials, live training and member perks. And new content is added EVERY Monday!
If you are creating a one page website in Divi, chances are you are going to be using anchor links in your primary menu to enable the user to navigate between different areas of the page.
The problem with this is that currently, Divi doesn’t provide any functionality to highlight an anchor link when the user is viewing the corresponding area of the page, which is not great for UX/UI.
There are a couple of guides around addressing this issue, but from what I have seen they:
- Are outdated and no longer work
- Only work with the default header format
- Only work when the anchor is clicked and not when the user scrolls
- Only work when all the content for each area is in a single section
- Use difficult to edit code
- Use a plugin
So I decided to create this up-to-date recipe that works:
- With the current version of Divi
- With all Divi’s header formats
- On both click and scroll
- For any number of sections per content area
- Using consolidated and easy to edit code
- Without using a plugin
So let’s get cooking!
Cooking time
It depends on how many menu items you have but it should generally take less than 10 minutes!
Preparation
For our prep we need to create our menu.
I am assuming you have your page content ready, and so you know which menu items you are going to need.
If you take a look at the demo you can see I have nine menu items. You may have more or less, it really doesn’t matter.
Navigate to Appearance > Menus and click create a new menu. Give your menu a name (mine is called Main Menu) and then click the Create Menu button.
Next, we need to add our menu items. Usually, we would add the pages we create, but as this is a one page site, we need to use custom links.
For each menu item you need, create a new custom link. In the URL field you will need to create a unique name for the content area it refers to and prefix it with a #, and then in the Link Text field, add what you want the menu item to be called.
You will likely want your first item to be Home.
When you have finished adding all your links, be sure to set the Display Location as Primary Menu, and then hit Save Menu.
Ok, that’s our prep done
Method
Now it’s time to work on our page. First create your page with all the content you want displayed. Don’t worry about how many sections you use for each content area, you don’t need to have all content for each area in a single section.
Next, open up the first section of your first content area, click the Advanced tab and in the CSS ID field, add the same unique name you used in the URL field for the custom link in your menu, but this time without the #.
Then in the CSS Class field, add the class ds-section and then save the section.
Next, open the first section of your next content area and repeat the process, using the unique name for that area in the CSS ID field, but the same ds-section class in the CSS Class field.
When you are finished, the first section in each of your content areas should have a unique CSS ID (which is the same as the custom link you created in your menu, but without the #) and the same CSS Class of ds-section.
All done? Great, now it’s time for some jQuery.
Here is what we are doing:
To start, we give our first menu item the class ds-menu-active. This is much the same as your home page link on a multipage site being active when you open the site.
Next, we create a variable called scrollPos to store the current vertical position which we will use later in a calculation.
Then we say, for each element with the class ds-section, create another variable called topPos so we can target that section when it is at the top.
Now we use both of the variables we created in a calculation that says, if a section with the class ds-section is equal to, or less than 80px from the top of the page, remove the class ds-menu-active from the previously highlighted item and add the class ds-menu-active to the current item.
jQuery(function ($) { $('#main-header #top-menu li:first-child a, .et_slide_in_menu_container .et_mobile_menu li:first-child a').addClass('ds-menu-active') $(window).scroll(function () { var scrollPos = $(window).scrollTop(); $('.ds-section').each(function (i) { var topPos = $(this).offset().top; if ((topPos - scrollPos) <= 80) { $('.ds-menu-active').removeClass('ds-menu-active') $('#main-header #top-menu a:not(li.centered-inline-logo-wrap a), .et_slide_in_menu_container .et_mobile_menu li a').eq(i).addClass('ds-menu-active') } }) }); });
We need to add this code into Divi, but we need to wrap it in script tags for it to work. So copy the complete code from the toggle below and then navigate to Divi > Theme Options > Integration > Add code to the < head > of your blog and paste it in.
If you have a tall main header, for instance when using the centered header format, you may want the your links to change a little earlier. If this is the case then just increase the 80 value in the jQuery until the links change at the point you want.
Complete jQuery
<script> //Highlight Active Links on Scroll and Click for One Page Divi Websites - By Divi Soup jQuery(function ($) { //Set first menu item as active $('#main-header #top-menu li:first-child a, .et_slide_in_menu_container .et_mobile_menu li:first-child a').addClass('ds-menu-active') $(window).scroll(function () { //Create variable to get the current vertical position var scrollPos = $(window).scrollTop(); //For each section with the class ds-section $('.ds-section').each(function (i) { //Create variable to calculate when to add active class var topPos = $(this).offset().top; //If the section is equal to or less than 80px from the top of the page if ((topPos - scrollPos) <= 80) { //Remove the active class from the previous menu item $('.ds-menu-active').removeClass('ds-menu-active') //Add the class to the current menu item $('#main-header #top-menu a:not(li.centered-inline-logo-wrap a), .et_slide_in_menu_container .et_mobile_menu li a').eq(i).addClass('ds-menu-active') } }) }); }); </script>
Now for a little CSS.
Our jQuery applies a CSS Class of ds-menu-active to our current/active menu item, but we need to add some styles to that class to change the appearance of that menu item.
All we are doing here is applying a different colour, but you can add in any styling you wish.
We use two selector strings. The first styles menu items when using the default, centered and centered inline header formats (including vertical navigation), and the second when using the slide-in and fullscreen header formats.
#main-header #top-menu a.ds-menu-active, .et_slide_in_menu_container .et_mobile_menu a.ds-menu-active { color: #FE437D !important; }
Copy the CSS above and paste into your child theme stylesheet or Divi > Theme Options > Custom CSS.
And that’s it! View your one page site and watch your menu items change colour as you scroll up and down.
If you found this helpful please leave a comment and subscribe to my newsletter for all my latest Divi related content.
Michelle X
Thanks! Nice and I particularly liked doing this without a plugin.
I’m trying to understand how I can exclude my first menu item from being highlighted (it’s just under the first section and there is no menu choice for the first section).
I’m trying to add :not(#top) to the css without success so far – like this:
#top-menu a:not(li.first-child a)
Looks like you got this sorted?
I love it!
how I can make it work for the last section that actually doesn’t have enough height to get close to the top so even though the anchor link works the effect it’s never executed?
Thank you!
You can make your last section taller or add an event to recognise the bottom of the window:
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
//do something
}
});
Super!
Great simple code. Thank you!
Thanks! this is a nice touch.
It’s amazing how something so simple can make a huge difference to a site.
Hello Michelle,
Always beautiful ideas!
Thanks for sharing.
Most welcome Gérard
Great! Thank you Michelle!
You’re very welcome
This is one of those questions that never had a good answer in the Divi community. It looks like we have now!
Thanks Nelson!