Problem
I have a 300-pixel-wide div that I want to scroll to the bottom of the content when the page loads. This div has dynamically added content and must be scrolled all the way down to the bottom. Now, if the user scrolls up, I don’t want it to return to the bottom until the user goes all the way down.
Is it possible to create a div that scrolls to the bottom unless the user scrolls up, and then stays at the bottom even when fresh dynamic content is added? I’m not sure how I’d go about doing this.
Asked by Robert E. McIntosh
Solution #1
I was able to get this to work using simply CSS.
Use display: flex and flex-direction: column-reverse to do this.
The browser considers the bottom to be the top. The only limitation is that the markup must be in reverse order if the browsers you’re targeting allow flex-box.
Here’s an example that works. https://codepen.io/jimbol/pen/YVJzBg
Answered by Jim Hall
Solution #2
This might be useful:
var element = document.getElementById("yourDivID");
element.scrollTop = element.scrollHeight;
[EDIT], to correspond to the comment…
function updateScroll(){
var element = document.getElementById("yourDivID");
element.scrollTop = element.scrollHeight;
}
Call the function updateScroll() everytime new content is added, or establish a timer:
//once a second
setInterval(updateScroll,1000);
If you just want to update if the user hasn’t moved, use the following syntax:
var scrolled = false;
function updateScroll(){
if(!scrolled){
var element = document.getElementById("yourDivID");
element.scrollTop = element.scrollHeight;
}
}
$("#yourDivID").on('scroll', function(){
scrolled=true;
});
Answered by Mr.Manhattan
Solution #3
This is something I recently implemented, and you might find it useful.
Say we have the following HTML:
<div id="out" style="overflow:auto"></div>
Then we can use the following command to see if it has scrolled to the bottom:
var out = document.getElementById("out");
// allow 1px inaccuracy by adding 1
var isScrolledToBottom = out.scrollHeight - out.clientHeight <= out.scrollTop + 1;
scrollHeight returns the element’s height, including any non-visible areas caused by overflow. clientHeight returns the CSS height of the element, or, to put it another way, the element’s actual height. You don’t have to worry about margins because both methods return the height without them. The position of the vertical scroll is indicated by scrollTop. 0 is the top, and max is the element’s scrollHeight minus the element’s height. When utilizing the scrollbar, it can be difficult to get it all the way down to the bottom (at least in Chrome). As a result, I included a 1px error. As a result, even if the scrollbar is 1px from the bottom, isScrolledToBottom will be true. This can be set to whatever feels good to you.
Then it’s only a question of setting the element’s scrollTop to the bottom.
if(isScrolledToBottom)
out.scrollTop = out.scrollHeight - out.clientHeight;
I’ve made a violin to demonstrate the concept: http://jsfiddle.net/dotnetCarpenter/KpM5j/
EDIT: Added a code snippet to demonstrate what happens when isScrolledToBottom is true.
Move the scrollbar to the bottom.
Answered by dotnetCarpenter
Solution #4
In 2020, you can use css snap, but before Chrome 81 the layout change will not trigger re-snap, a pure css chat ui works on Chrome 81, also you can check Can I use CSS snap.
If the last piece is visible, this demo will snap it; scroll to the bottom to see the effect.
EDIT
Scroll up easier with scroll-snap-type: y proximity;
Answered by wener
Solution #5
$('#yourDiv').scrollTop($('#yourDiv')[0].scrollHeight);
Live demo: http://jsfiddle.net/KGfG2/
Answered by Alvaro
Post is based on https://stackoverflow.com/questions/18614301/keep-overflow-div-scrolled-to-bottom-unless-user-scrolls-up