WIP: Nav Menu widget making all anchor links on current page show "active" color at the same time

Browser: Chrome, Safari, Firefox
OS: MacOS
URL: https://bricks-menu-anchor.jtx.host/

I have set up a WP menu in Appearance > Menus which contains some links to pages on the site (Home, Tour, Contact), and some “Custom Link” anchors to scroll to IDs on the home page. E.g. “/#music” and “/#videos”. So sort of a hybrid one-pager site. I have set an “Active” color (Nav Menu widget > Top level > Active Typography) which in this case is red, to indicate to the user the current page they are on (e.g. Home is red on the home page, Contact is red on the Contact page)

Please forgive me if this not a bug and I’m just missing something here. When I am on the Home page, which contains the #music, #videos and #subscribe elements, the menu is showing active/red on Home, Music, Videos, Subscribe all at the same time. This presents as weird and broken to me. I am thinking this might be a bug because I cannot imagine anyone would want this. I don’t recall experiencing it in other builders/themes or websites that I’ve visited. I’d expect normal behaviour to just have Home as active (the current page) and leave it at that, or dynamically change colors as you scroll (not expecting Bricks to do this - it would be nice, but I can achieve this with a 3rd party plugin).

Please advise. Thank you.

Same here. Would be awesome to have a feature for this in future Bricks versions!

1 Like

It seems it is active for the page you are on. The anchor links are all on the same page so it will show the menu item active for any anchor link you choose on that page.

In my experience with other builders and themes and browsing websites over the years, anchor links which scroll to part of the page shouldn’t be their active color until you are on that section of the page or you click on them. Elementor works perfectly like this, as do popular themes I’ve used. Instead Bricks just lights up all anchor links as active at the same time before you even click on anything and they stay like that. It’s a weird user experience that makes no sense to me.

Submenu links will not change colors either. The top level link, even if it does not go to a page, will change colors if a submenu link is clicked, but the submenu link itself won’t.

This is actually only a few lines of javascript code to make it work. I have my own javacode for the nestable nav menu so the submenu links work. If I had time, I would make the the anchor links work.

Email help@bricksbuilder.io and complain about it. :smiley: Tell them we want submenu links to change colors too.

I never mentioned submenu links. I don’t think I’ve communicated the issue to you very well. Hopefully the Bricks team understand what Matt Eastwood and myself are referring to. Currently if you want normal behaviour from a main menu with anchor links you need to go install a 3rd party plugin or add custom JS. Which I have done. But it would be good for the future to get this usable.

I just realised the original example link in the post is not working. Here is an updated one: https://bricks-menu-anchor.jtx.host/

I fully understand what you are saying. I am also saying, along with your desire for only the anchor link that is clicked to change color, the desire for submenu links to change color is needed too. :slightly_smiling_face:

Ahh I see. Sorry about that. My misunderstanding! I’m defensive about this issue as some people act like it isn’t one haha.

Hey @mindpattern ,
Sorry for the delayed reply.

I can replicate the issue. However, it’s more of an improvement than a bug because there is no code to provide the desired behavior. So I created an improvement task for it.

Best regards,
timmse

2 Likes

If the problem still exists. Unfortunately, Bricks does not set a class for active navigation elements, which is a real omission. Hopefully it will be fixed soon. Until then you can create them yourself with a JavaScript code.

First of all, please excuse my bad English. Assuming you use the standard navigation (the old one) and a template for the header (but it should also work if you integrate the navigation menu directly into the one-pager).

  1. first, of course, you should set up your one-pager menu properly so that it works.

  2. in the next step, add the following JavaScript under Bricks/ Settings / Custom Code / Header Scripts (make sure that your own scripts are allowed - Same Settings Page → Enable code execution).

<script>document.addEventListener('DOMContentLoaded', function () {
    const navLinks = document.querySelectorAll('.menu-item');

    navLinks.forEach(link => {
        link.addEventListener('click', function () {
            // Remove the 'active-link' class from all links
            navLinks.forEach(link => link.classList.remove('active-link'));

            // Add the 'active-link' class to the clicked link
            this.classList.add('active-link');
        });
    });
  });</script>

The script adds another class called .active-link to the clicked active element with the .menu-item class.

You can now address this class via CSS, e.g. .active-link a {color: #FFFF00!important;}. The Important may be required, depending on how specifically you define the class.

I just did it successfully on my site, so I can post it here quickly. I hope it works for you!

Hi guys,

Does anyone know if this issue has been resolved in Bricks or if there is an alternate fix to it?

The js provided above seems to be working in the sense that now the active link (#anchor) is the same colour as all the other menu nav items but it seems that there is another class with more specificity and not allowing it change to alternate colour. This is frustrating because if you navigate to another page then that active page/link does not change colour in the nav menu either…

Any help would be much appreciated!

Solution for your issue:

Dont forget, if your section is too big, than add ID to something smaller for you anchor.

Hope this will help you.

<script>
document.addEventListener('DOMContentLoaded', function () {
    const navLinks = document.querySelectorAll('.menu-item a');
    const sections = [];

    // Create an array of sections corresponding to each nav link
    navLinks.forEach(link => {
        const section = document.querySelector(link.getAttribute('href'));
        if (section) {
            sections.push({
                link: link,
                section: section,
            });
        }
    });

    // Function to remove 'active-link' class from all links
    function removeActiveClass() {
        navLinks.forEach(link => {
            link.parentElement.classList.remove('active-link');
        });
    }

    // Create Intersection Observer with lower thresholds for better section tracking
    const observer = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                removeActiveClass();

                // Add active-link class to the visible section's link
                const activeLink = document.querySelector(`a[href="#${entry.target.id}"]`);
                if (activeLink) {
                    activeLink.parentElement.classList.add('active-link');
                }
            }
        });
    }, {
        threshold: [0.1, 0.25, 0.5] // Lower thresholds to trigger earlier for large sections
    });

    // Observe each section
    sections.forEach(({ section }) => {
        observer.observe(section);
    });

    // Smooth scroll to anchor links
    navLinks.forEach(link => {
        link.addEventListener('click', function (e) {
            e.preventDefault(); // Prevent default anchor behavior
            removeActiveClass(); // Remove active-link class from all links
            this.parentElement.classList.add('active-link'); // Add active class to the clicked link

            const targetId = this.getAttribute('href').substring(1);
            const targetSection = document.getElementById(targetId);

            // Scroll smoothly to the section
            window.scrollTo({
                top: targetSection.offsetTop - 50, // Adjust for fixed headers
                behavior: 'smooth'
            });

            // Manually check the section after scrolling
            setTimeout(() => {
                observer.takeRecords(); // Force observer to check current visibility
            }, 300); // Add a delay to ensure scroll is completed
        });
    });

    // Add a scroll listener to force a check when scrolling ends
    let isScrolling;
    window.addEventListener('scroll', function () {
        window.clearTimeout(isScrolling);
        isScrolling = setTimeout(function() {
            observer.takeRecords(); // Re-check sections after scrolling stops
        }, 200);
    });
});
</script>

You need to add some CSS like this:

.active-link a{ background-color: #04276e!important; color: #ffffff!important; }

Hi guys,

We’ve improved this in Bricks 1.11 BETA, now available as a manual download (Bricks – Account)

Please let us know if you are still experiencing issues.

You can see the full changelog here: Bricks 1.11 Changelog – Bricks

As with any beta release, please do not use it on a production/live website. It is only meant for testing in a local or staging environment.

Best regards,
Matej

2 Likes

Hello Matej, I am not sure, if this is in production already? I expect to change the active link on scroll, but it isn’t. How can I set it up properly?

Here is my site: Borgy

Edit - I have found this snippet, which works flawlessly: GitHub - werkmind/Bricks-Anchor-Navigation: The perfect Bricks Builder Addon for Local Navigation Menus (Anchor Links)

Hi,

The solution with Bricks should work on click and on page refresh, but not on scroll. So I’m glad that you found a solution with that snippet - it looks like it works perfectly for your case.

Best regards,
Matej

Hello Matej, how are you doing?

Besides the anchor link part, when using the nestable nav menu, all my links remain in the active state even using different urls. Take a look below if possible.

https://www.awesomescreenshot.com/video/35061184?key=3899cfc35764440c8af9d4e4a4af2cd2

Best regards,

I think there is something to do with JetEngine’s Profile Builder Account page set to “Content”.

Hi @ribeirom4e,

so, just to make sure I understand it correctly. If you change this, it will work? If that’s the case, then I can mark it as no bug.

Please let me know,
Matej

Didn’t try it because it will screw me up a little. It is an assumption.

Basically, when we set the template mode to “content”, we stay in the account page and the sub-pages are loaded as content inside a block. But, the url is changed normally (that is its advantage).