Bootstrap type Scrollspy sidebar navigation -some minor bugs

It’s been a while since I worked on this (oops! over 2 years) after having received a lot of help in the thread entitled “Bootstrap docs” sidebar nav -problems getting it to work! and I thought I’d take a look at it again so I can finalize my website ideas :blush:

Things appeared to work fine in Firefox 115 (Mac) so I’ve worked a bit on the user interface, but noticed that there are actually some strange things going on…

1) Invisible nav-items: for some reason the nav-items (the “button/pill” in blue showing where in the navigation you are) is completely gone. Hovering still works, and functionality wise it scrolls to where I click in the navigation area, but the item is no longer highlighted.
It’s usually remidied if I do a page reload in Firefox 2 or 3 times, so I don’t know if this is a Codepen issue or something else. I’m having the same problem in Safari 14 (Mac), Opera 98 (Mac) and Safari (not sure which version) on an iPad running iPadOS 16.7.2.

2) scrollbar in navigation not following content to top-scroll: I currently have 15 items and several sub-items(i.e. items 10-15 all open with additional sub-items) and if the screen space isn’t high enough to display them all a scrollbar in the navigation section appears. This works great except it doesn’t scroll along with the page content if you use the mouse-wheel to scroll up/down. Try this:

  1. Adjust the browser height so that there’s not enough vertical space to show all 15 main items. A scroll-bar will appear in the navigation section
  2. Now using the scroll-wheel on the mouse, or the scroll-bar on the right side of the browser window, scroll up and down in the content of the window. Notice that the left scroll-bar (the one in the sidebar navigation) doesn’t follow, so you need to “manually” drag that scroll-bar to wherever you are in order to “catch up” with the highlighted item in the sidebar-navigation)

3) Disable hovering effect for current item: say you’ve scrolled down to (or clicked on) item 2 in the sidebar-navigation (which highlights it in blue). When hovering over other items those turn light-gray under the mouse-pointer, but for an item which is already selected (the same goes for sub-items) I would like that effect to go away (i.e. if I hover over a selected item it should just stay blue).
Here’s an example of a page working like that, using a similar type of sidebar navigation.
(I tried to find out more by looking at the source but i’m not sure if I figured it out. Might be a ready-made Wordpress thing, according to what I read in the source).

Thanks :grinning:

This seems to be a downside of the scrollbar spy nav and I see that it was reported way back and never fixed.

You can try scrolling the item into view with some js and that may solve the problem.

Here was my attempt buit beaks if the user selects a nav item…

  $(window).on("activate.bs.scrollspy", function () {
    document
      .querySelector("#sidenav > .nav-link.active")
      .scrollIntoView({ block: "start" });
  });

I added it to a forked demo of your page.

That seems to work ok if just scrolling but doesn’t work if the left item is clicked unfortunately. Maybe a JS guru can jump in here and fix it :slight_smile:

Note that my page has no horizontal scrollbar at the bottom because you missed out the bootstrap container class which must encompass a row or the negative margins drag it outside the viewport.

I couldn’t replicate this but I may have misunderstood. Maybe a screenshot could help me see what you see.

This should do it.

.flex-column > .nav-link.active:focus, 
.flex-column > .nav-link.active:hover{
  background:royalBlue;
  color:#fff;
}

Nice to see you again Paul, and thanks for replying!

Oh, I see.
Yes, the demo in the links also clearly shows the issue -that the active item goes beyond what’s currently visible in the nav section until you go there any scroll up or down to reveal it again.

It’s irritating to have to do this (and not visualy appealing), but IMHO something that most people can figure out, and they’ll reach for the navigation scrollbar to remedy it.

Very neat to see that the navigation-scrollbar moves and reveals the current item at any time! I see what you mean about it breaking though, which is a more serious problem than keeping it as is

Indeed!

I’m not sure what you mean, but I will look into it. I see that in my version there’s a horizontal scrollbar present all the time, regardless of how wide I resize the browser window. I’m guessing this has something to do with this missing container class?

Sorry about being unclear.
Come to think of it, it might be part of the previous issue discussed above…

What happens is that sometimes the blue “active item” highlight is gone completely!
This may happen when I visit the page for the first time, or after I’ve made some edits to the code.
Functionality is still working apparently (I can click on say item 4 in the navbar and it scrolls down to section 4 in the main window,but the blue item highlight is completely gone! Here’s a screenshot:
invisibleitem1

But if I hover the mouse over an item the gray highlight is visible as seen here:

I also noticed that if I scroll down (in the text-content) to a sub-item (i.e. item 15-4) the sub-items still don’t open in the navbar as seen here:
ivinsibleitem3

Finally, I also noticed that the navigation scrollbar appears as before if I resize the browser window to become shorter in height, but again no current item highlight is to be be seen:
invisibleitem4

The issue is usually remedied after clicking the browser’s “reload” button 1-3 times. Reloading the page is also what introduces the issue, so maybe it has something to do with the page-loading process, and perhaps it’s a codepen issue, and not the code itself.
Can you reproduce the problem at your end by doing the following?:

  1. Go to my Codepen example her: https://codepen.io/CodeDecoder/full/WNWNKWw
  2. Click on any navbar item (or scroll down within the page’s text-content section). The item you clicked should be highlighted in blue.
  3. If no item turns blue (regardless if you click on an item in the navbar, or scroll up/down), press the browser’s “Reload” button.
  4. Does an item now highlight in blue?
  5. If it still doesn’t, press the browser’s “Reload” button again. Repeat if necessary until it does. I’ve experienced having to do this perhaps up to 4-5 times in a row.

Perfect! Thanks!
I duplicated the font-weight from the active item so that wouldn’t change either:

.flex-column > .nav-link.active:focus, 
.flex-column > .nav-link.active:hover{
  font-weight: 500;
  color: White;
  background: RoyalBlue;
}

Hmmm can’t replicate that on my system unfortunately. I’m on a PC at the moment as my iMac died a couple of weeks ago so I can’t check different platforms anymore.

It does sound like a redraw issue if its cleared up by resizing the window. You may need to force a reflow of the page in the JS somewhere which could be done by querying the elements offsetWidth but would have to be integrated from an event in the scrollspy code. (There was an example of using the event in my demo).

Sorry to hear about that. I’m on the opposite side, not having any PC to try it out on. Maybe I should look at setting up a virtual environment in order to get a Windows setup.

Anyone else reading who could try it out?

This is way over my head, I have to admit. Although I (atleast I think I do) understand in general terms that something in the JS code needs to be reloaded/reset.

I did however get an idea… to export all the code from Codepen (“Export” button at bottom of page), then try it locally on my own Mac.
So far I’ve only done a copuple of quick test in Firefox and Safari (Mac), but here it worked every time after doing a browser “Reload”. The strange thing is that it “remembered” the last position (i.e. the item I had had clicked on, so regardless of how many times I did a browser reload it didn’t reset and start at the top of the page but rather went to the item/section I had last clicked on.
Note: This also applies if I do a “force reload” (holding down SHIFT while clicking on the “reload” button in the browser) which I hadn’t expected.

Interestingly I also noted that only what I had clicked in in the sidebar nav was remembered!
In other words, if I clicked on item 7 in the navbar, then did a browser reload it presented the page with item 7 active. And if I then scrolled (in the main content window) with the mouse’s scroll-wheel (or used the scrollbar on the right of the browser window) to say section 2, then did a browser reload: it opened the page again at section 7.

Also the “back to top” button didn’t get remembered either, but I suppose that’s really just another way of scrolling in the content page.
UPDATE: silly me! It’s the HTML anchor element kicking in of course! I just noticed it in the URL field.

I don’t know what to make of this, but there’s definitely a difference in how it works online and offline.

When you click reload it will load the current url in the address bar which if you have already clicked a nav link will now have the fragment identifier appended to the url so the reload will most likely take you to the destination of the fragment identifier.

Thats how you can link to specific sections directly from a url.

Note that when you are working in codepen you are not working on a normal page. Your html is sandboxed in an iframe so the concept of urls is different as it’s the codepen url that refreshes and not your displayed code (unless you have the pro edition of codepen and then you can get a live view outside of an iframe).

When there are odd glitches in codepen its best to test on a live online page or a local page outside of codepen to see if the same glitch occurs. There are also often differences between testing online and locally in that online there will be some latency and this may show up some problems that are not evident running locally because they happen more quickly locally,

Good explanations!
Let’s hope the random missing item issue is just a glitch within Codepen, but I’ll keep testing it in different environments.

As for what you said earlier:

Note that my page has no horizontal scrollbar at the bottom because you missed out the bootstrap container class which must encompass a row or the negative margins drag it outside the viewport.

Ah! I see it’s basically something that affects the whole page structure.
I looked it up here and accordingly added the following CSS:

.container {
    background-color: Purple;
} 

(the purple being as an aid to see what I was affecting).

and in HTML added the following at the very top (right after the JS script source URL):

<div class="container">

finally, at the very end of the HTML document:

</div>

This resulted in my case the horizontal scroll-bar gone in my case (it’s always been present, in the middle) regardless of how I resized the browser window.
However, in a fork of the same pen it acted differently: when resizing the browser window to 991px (or less) the horizontal scrollbar appeared and let me move the entire purple box (along with its contents within) to the left and right. I assume this is the intended behaviour?

I will have to compare the two pens line by line because they’re supposed to be the same (except for the JS in the latter pen which allows smooth-scrolling in both old and new browsers, but even adding that code didn’t make any difference). Here’s the original one:

UPDATE: never mind! The difference between the two was the topmost one having a rather long title in the header which the second one didn’t have. This made the difference in seeing the scroll-bar or not.

So this sidebar nav appears to work more or less as intended now, but I’ll see about finding a JS solution for the “follow the page content scrolling” issue when the horizontal scroll-bar in the navigation sidebar appears. I suppose the Javascript section of this forum would be a more suited place for that.
Other than that, in your (or someone else reading’s opinion) does this sidebar nav appear to work well (both functional and user-interface related) and make for a user-friendly experience (it will be for a long FAQ section), or are there still things I should consider adding/changing?

1 Like

In bootstrap you must have a container followed by a row followed by a column. All 3 work together -the negative margins match the padding to create gutters. You can’t change padding or margins without breaking one or the other. That’s why they’re best left alone until you realis what the effect will be.

If you want full width header and footer then you can put them inside a container-fluid class which is what I did for your footer in the demo I posted. The container-fluid must be a direct child of the body and not nested inside another container.

I think I may have worked it out now. The bootstrap container should be OK now as well as a few closing /nav and /div tags that were missing.
I’ve also replaced the smooth-scroll JS with one that works with both old and new browsers.

The code validates with Codepen’s “analyze” features. Does it seem OK at your end?

Yes seems ok to me.

It still has your original issue in that any links near the end of the scrollable left section are not showing unless you scroll the sidebar. I don’t see its a big issue though.

I agree.
It’s a minor issue which most people can figure out by themselves.

But if there’s an easy fix (i.e. another JS which replaces ScrollSpy) I’m all for it :+1:
For now though it seems I have a working sidebar navigation and can go ahead with the rest of my site.
Thanks again for all your help and feedback! :grinning:

1 Like