I'm having a problem with Bootstrap Scrollspy component.
I'm using a sticky-top
navbar and when the nav button is clicked it scrolls to the correct element;
But the problem is that the sticky navbar is overlaying this element.
I tried using data-offset = "50"
in the body tag but it affected nothing.
The body tag:
<body data-spy="scroll" data-target="#sectionsNav" data-offset="50">
The body tag css:
body {
position: relative;
overflow-y: auto;
}
The navbar:
<nav class="navbar navbar-light bg-light sticky-top">
<div id="sectionsNav">
<ul class="nav nav-pills text-center">
<li class="nav-item">
<a class="nav-link" href="#wihe">What is Home Eats</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#hiw">How it Works</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#pws">Problems we Solve</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#jhen">Join Now!</a>
</li>
</ul>
</div>
</nav>
How it works div:
..
<div id="hiw" class="container">
...
..
.
</div>
..
Expected Behavior on clicking How it works button in the nav:
Occurring Behaviour:
Note That: The navbar is above How it Works header.
After applying @SMAKSS answer the scroll worked as charm. But another problem occured, in the navbar the highlighted element becomes the previous element.
At the following screenshot I pressed on How it Works and it scrolled correctly, But the highlighted navbar element is What is home eats which is the previous one. i.e. If I clicked on Problems we Solve, How it Works becomes selected. It always select the previous one.
I fixed the second problem by doubling the data-offset
attribute to be 100.
the code now looks like this:
<head>
<style>
html {
scroll-padding-top: 70px;
}
body {
position: relative;
overflow-y: auto;
}
</style>
</head>
<body data-spy="scroll" data-target="#sectionsNav" data-offset="100">
...
.
</body>
The problem here happens when an element with position fixed
comes into play. Although we still jump to the desired id
, it won't recognise that we have a fixed position element. So it will ignore its height
and jump wherever the element with a specific id
matches the window top element.
To solve this, you need to add padding
to your scroll jumps, like below:
html {
scroll-padding-top: 70px; /* height of sticky header */
}
Learn more about scroll-padding
in CSS-Tricks.
As we have gone further on this solution, the spying behaviour crashed since the scroll spy will only know whether we are in a section with a specific ID. So to fix this, there are several approaches like adding padding
to each section according to navbar height
or, as @Raamyy suggested approach, we can define data-offset
on our body
tag, respecting the height of the fixed
navbar. You can read bootstrap scrollspy options for more information about data-offset
.