I have a terminal-like contentEditable div. I'd like new output to cause it to scroll the window so it is in view, unless the user has manually moved the scroll bar to be viewing another position. In that case, I wish to leave it viewing the position they were at.
I'd prefer to avoid doing this with JavaScript hooks or timer callbacks if at all possible. So I was interested in a promising CSS-only solution of using display: flex
with flex-direction: column-reverse;
. (A comment on that solution explains that you can avoid the hassle of the reversal of elements by using an outer container with the attribute.)
Borrowing a snippet from another one of those answers, here is a demonstration that this technique works--in my browser--but only for a fixed-size div.
const inner = document.getElementById("inner")
let c = 0
setInterval(function() {
const newElement = document.createElement("div")
newElement.textContent = "Line #" + (++c)
inner.appendChild(newElement)
}, 500)
#outer { /* contents of this div are reversed */
height: 100px;
display: flex;
flex-direction: column-reverse;
overflow: auto;
}
#inner { /* this div has content in normal order */
}
<div id="outer"><div id="inner"></div></div>
<p>To be clear: We want the scrollbar to stick to the bottom if we have scrolled all the way down. If we scroll up, then we don't want the content to move.</p>
But changing that to 100% instead breaks it. Same for height: auto
. Is there any magic I can apply to keep the behavior and use 100% height?
const inner = document.getElementById("inner")
let c = 0
setInterval(function() {
const newElement = document.createElement("div")
newElement.textContent = "Line #" + (++c)
inner.appendChild(newElement)
}, 500)
#outer { /* contents of this div are reversed */
height: auto;
display: flex;
flex-direction: column-reverse;
overflow: auto;
}
#inner { /* this div has content in normal order */
}
<div id="outer"><div id="inner"></div></div>
<p>Having changed it to 100%, new content never gets scrolled into view, even if the scroll bar was "stuck" to the bottom</p>