FradistaFicko
FradistaFicko

Reputation: 47

CSS overflow-y: scroll overwrite my code and other functions not working

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"> &#11167; </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

Answers (3)

Neelansh Mathur
Neelansh Mathur

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

SMAKSS
SMAKSS

Reputation: 10520

What is happening here?

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).

How to fix it?

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

Farista Latuconsina
Farista Latuconsina

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"> &#11167; </button></a>
  </div>
  <div class="content second" id="second">
  
  </div>
</div>

Upvotes: 2

Related Questions