Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent browser viewport from sticking to bottom when page height increases in runtime?

Tags:

javascript

css

Modern browsers seem to have a feature where the viewport sticks to bottom when page height increases. What actually happens is that browser scrolls the viewport at the same rate as height being increased when initial position is at (or very close to) the bottom of the page. This results in appearance as if page is expanding upwards instead of downwards.

How can this feature be disabled for a certain page using CSS or JS, so that the page would always visually expand downwards?

This of course, also happens when added element's height is expanded animated. For this reason, if possible, I would want to avoid resetting scroll position afterwards to prevent visible jump. The demo of this "feature" (that seems to happen only within rare conditions) interacting with the viewport and drop animation can be observed in the gif below.

enter image description here

I know there must be a way, otherwise every site with infinite scroll would suffer from an infinite loop. Counter argument: Chrome appears not to do this for containers that surpass certain height limit. So maybe infinite-scroll sites don't even bother addressing this in their sites.

like image 313
Slava Avatar asked Oct 30 '22 03:10

Slava


1 Answers

Check this fiddle. You can observe that in Chrome, the first container snaps to the bottom, while the other divs has a scroll relative to the top. In Firefox or IE 11, you cannot observe this behavior.

This happens when the top bound of the last element on a scroll container is above the top bound of the container. The browser decides that the last element is what the user is interested in and decides to stay in that position.

The last div doesn't snap to the bottom because the scroll happens relative to the top bound of the last element and the last element is growing.

If you want a different behavior, I would not suggest handling it with Javascript, but I would suggest changing your layout considering these rules. For example the last div should be the growing one, instead of the previous siblings of it.

Obligatory code:

var div = document.querySelectorAll('.growing');
var height = 500;

setInterval(function(){
	height += 100; 
	div[0].style.height = height + 'px';
	div[1].style.height = height + 'px';
  div[2].style.height = height + 'px';
},1000);
.start, .end{
  height: 110px;
}
.start{
  background: red;
}
.end{
  background: green;
}
.growing{
  background: yellow;
}
.cnt1,.cnt2,.cnt3{
  overflow: auto;
  border: 5px solid black;
  margin: 5px 0;
  scroll-snap-type: mandatory;
}
.cnt1{
  height: 100px;
}

.cnt2{
  height: 120px;
}

.cnt3{
  height: 100px;
}
<div class="cnt1">
  <div class="start"></div>
  <div class="growing"></div>
  <div class="end"></div>
</div>
<div class="cnt2">
  <div class="start"></div>
  <div class="growing"></div>
  <div class="end"></div>
</div>

<div class="cnt3">
  <div class="start"></div>
  <div class="end"></div>
  <div class="growing">
    Content
  </div>
</div>

Edit: If the bounds of the growing div is in the visible area, the scroll is relative to the top of the growing div. So you can hack CSS to show the growing div, but actually not show it.

In this fiddle I have used two different CSS hacks. First one is adding a negative margin bottom and a positive padding bottom at same amount. The second hack is adding an :after element to the growing div but hide its visibility.

like image 115
Gokhan Kurt Avatar answered Nov 15 '22 05:11

Gokhan Kurt