How to auto scroll down when new messages added

Chat development and vertical scrolling

Recently developed a WebApps chat for telegram and came across the fact that when you add new messages to the chat, you need to automatically scroll through the message container. The messengers and chats has same UX 🤷.

“Standard” implementation is done with JS and scrollTop. These solutions are easy to google, but that’s not what we’re talking about today.

Scrolling with pure CSS

While searching for a solution to this problem, I accidentally discovered another scrolling method. The method is to use pure CSS 😲 and the flex-direction property. This method will work if you add a wrapper for the content inside the scroll element.

The trick is to change the direction of the content using the column-reverse value in the scroller. Because the elements are in a different container, they are not “flipped” but instead are lined up at the bottom. This causes the scroller to scroll down when adding content.

An added bonus: the scroll position is saved.

The method is cool because there are no annoying jumps when adding new messages and no extra code 🔥 is needed to keep track of the current scroll position.

In case the user scrolls up, the scroller will not lose the scroll position when adding new messages. The scroller will “stick” to the bottom only if it is already set to the bottom, by default or by the user.

DEMO

Css:

.chat {
    overflow: auto;
    height: 300px;
    display: flex;
    flex-direction: column-reverse;
}

.chat-content {
    padding: 20px;
    max-width: 500px;
    margin: auto;
    width: 100%;
}

.msg {
    position: relative;
    max-width: 75%;
    padding: 7px 15px;
    margin-bottom: 5px;
}

HTML:

<div class="chat">
    <div class="chat-content">
        <div class="msg sent">Message 1</div>
        <div class="msg rcvd">Message 2</div>
        <div class="msg sent">Message 3</div>
        <div class="msg sent">Message 4</div>
        <div class="msg sent">Message 5</div>
        <div class="msg rcvd">Message 6</div>
        <div class="msg rcvd">Message 7</div>
    </div>
</div>

<br/><br/>
<div class="btn">
    <button id="addItems">Add message</button>
</div>

Button handler for adding new messages:

let chatContent = document.querySelector('.chat-content');

document.getElementById('addItems').addEventListener('click', function() {
    let newMsg = document.createElement('div');
    newMsg.classList.add('msg', (chatContent.children.length % 2) ? 'sent' : 'rcvd');
    newMsg.innerHTML = "Message " + (chatContent.children.length + 1)
    chatContent.appendChild(newMsg);
});

You can see a working example on CodePen.