Reputation: 47
I have a button, which scrolls down to the next div, when I click on it. It has a nice 'animation' with smooth scrolling.
I also have a div fixed in the top, which width growing as you scrolling down. It is working fine until I write this line to container's CSS: overflow-y: scroll;
As overflow-y is set to scroll, the width of my div doesn't grow anymore, but if I remove this line my smooth scrolling animation stop working.
Here is my code.
HTML:
<div id="scrollbar-border-top"></div><div id="scrollbar-border-inside"></div><div id="scrollbar"></div><div id="scrollbar-border-bottom"></div>
<div id="container">
<div class="content first">
<a href="#second"><button type="button" class="btn btn-outline-success" id="gomb_kovetkezo"> ⮟ </button></a>
</div>
<div class="content second" id="second">
</div>
</div>
CSS:
#container {
width: 100%;
height: 100vh;
scroll-behavior: smooth;
overflow-y: scroll;
}
.content {
display: flex;
flex-wrap: wrap;
width: 100%;
height: 100vh;
justify-content: space-between;
margin: 0;
z-index: 1;
background-image: url("../img/bg2.jpg");
background-position: center center;
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
}
.first {
background-color: lightblue;
}
.second {
background-color: red;
}
#scrollbar {
width: 0%;
height: 5px;
background-color: red;
position: fixed;
top: 5px;
z-index: 3;
}
#scrollbar-border-top {
width: 100%;
height: 5px;
background-color: black;
position: fixed;
top: 0px;
z-index: 2;
}
#scrollbar-border-bottom {
width: 100%;
height: 5px;
background-color: black;
position: fixed;
top: 10px;
z-index: 2;
}
#scrollbar-border-inside {
width: 100%;
height: 5px;
background-color: black;
position: fixed;
top: 5px;
z-index: 2;
}
JavaScript:
document.addEventListener("scroll", scrollHappened);
function scrollHappened(event) {
var scrollableHeight = document.body.scrollHeight-window.innerHeight;
var scrollPosition = window.scrollY;
var percentage = scrollPosition / scrollableHeight *100;
var scrollbar = document.getElementById("scrollbar");
scrollbar.style.width = percentage + "%";
}
Is there any way to make both of my functions work?
Upvotes: 2
Views: 1084
Reputation: 706
This question intrigued me. Here is the answer.
Set the link's href
attribute to #
for the time being. Add an id to your link, I've used mylink
for my code below.
Add this javascript to the already existing JS on your fiddle:
var link = document.getElementById("mylink");
var target = document.getElementById("second");
link.addEventListener("click", (e) => {
e.preventDefault();
target.scrollIntoView({behavior: "smooth"});
});
Your link would look like:
<a href="#" id="mylink">
Let me know if this works for you :)
Upvotes: 1
Reputation: 10520
Since your animation works with window.innerHeight
whenever you try to add overflow: scroll
to your container
it will disable the window scrolling, in order to have only one active scrollbar at the same time (This is not actually happening but it is the problem(ish)). So the calculation of document.body.scrollHeight - window.innerHeight;
will be 0
then your header animation wont fill ever due to this equation var percentage = scrollPosition / scrollableHeight * 100;
(the scrollableHeight is zero so the result will be infinity).
So the best way to fix this issue is to determine the active scrollbar and assign scroll-behaviour
to it's parent. Since in normal flow your active scrollbar is depended on body
itself you should remove overflow-y: scroll;
from your container and then add scroll-behavior: smooth;
to the active scrollbar parent
So your final output should be something like this:
html,body {
scroll-behavior: smooth;
}
#container {
width: 100%;
height: 100vh;
}
...
Upvotes: 1
Reputation: 343
It looks like you have to change the anchor to container element. Below is the example of working snippet.
document.addEventListener('scroll', scrollHappened, true);
function scrollHappened(event) {
var element = document.getElementById('container');
var scrollableHeight = element.scrollHeight-element.clientHeight;
var scrollPosition = element.scrollTop;
var percentage = scrollPosition / scrollableHeight *100;
var scrollbar = document.getElementById("scrollbar");
scrollbar.style.width = percentage + "%";
}
#container {
width: 100%;
height: 100vh;
scroll-behavior: smooth;
overflow-y: scroll;
}
.content {
display: flex;
flex-wrap: wrap;
width: 100%;
height: 100vh;
justify-content: space-between;
margin: 0;
z-index: 1;
background-image: url("../img/bg2.jpg");
background-position: center center;
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
}
.first {
background-color: lightblue;
}
.second {
background-color: red;
}
#scrollbar {
width: 0%;
height: 5px;
background-color: red;
position: fixed;
top: 5px;
z-index: 3;
}
#scrollbar-border-top {
width: 100%;
height: 5px;
background-color: black;
position: fixed;
top: 0px;
z-index: 2;
}
#scrollbar-border-bottom {
width: 100%;
height: 5px;
background-color: black;
position: fixed;
top: 10px;
z-index: 2;
}
#scrollbar-border-inside {
width: 100%;
height: 5px;
background-color: black;
position: fixed;
top: 5px;
z-index: 2;
}
<div id="scrollbar-border-top"></div><div id="scrollbar-border-inside"></div><div id="scrollbar"></div><div id="scrollbar-border-bottom"></div>
<div id="container">
<div class="content first">
<a href="#second"><button type="button" class="btn btn-outline-success" id="gomb_kovetkezo"> ⮟ </button></a>
</div>
<div class="content second" id="second">
</div>
</div>
Upvotes: 2