How to scroll the last message from user to the top of chat container

How to scroll the last message from user to the top of chat container
javascript
Ethan Jackson

Automatically scroll a fixed-height chat viewport so that each new user message is positioned flush at the top—pushing earlier messages upward and out of view (only visible by scrolling)—just like ChatGPT. Messages remain in chronological order (top-to-bottom) in the DOM, but when an assistant reply is added and causes overflow, the container should scroll to the bottom to reveal that latest content. How can I implement this behavior using JavaScript and CSS

<!DOCTYPE html> <html> <head> <style> .chat-container { display: flex; flex-direction: column; height: 100vh; } .chat-header { padding: 1rem; background: #444; color: white; } .chat-messages { flex: 1 1 auto; min-height: 0; overflow-y: auto; border: 1px solid #ccc; padding: 1rem; display: flex; flex-direction: column; gap: 0.5rem; } .message { max-width: 70%; padding: 0.5rem; border-radius: 1rem; } .user { background: #007aff; color: white; align-self: flex-end; } .bot { background: #ddd; color: #333; align-self: flex-start; } .composer { padding: 0.5rem; border-top: 1px solid #ccc; } .input { width: 80%; padding: 0.5rem; } .send-btn { padding: 0.5rem 1rem; } </style> </head> <body> <div class="chat-container"> <div class="chat-header">Chat Demo</div> <div class="chat-messages" id="msgs"> <div class="message bot">Welcome!</div> </div> <div class="composer"> <div id="input" class="input" contenteditable="true"></div> <button id="send" class="send-btn">Send</button> </div> </div> <script> const msgs = document.getElementById('msgs'); const inputEl = document.getElementById('input'); const sendBtn = document.getElementById('send'); function addMessage(text, cls) { const m = document.createElement('div'); m.className = `message ${cls}`; m.textContent = text; // I append chronologically: msgs.appendChild(m); // then try to scroll the new message into view at the top: m.scrollIntoView({ behavior: 'smooth', block: 'start' }); } sendBtn.addEventListener('click', () => { const txt = inputEl.textContent.trim(); if (!txt) return; addMessage(txt, 'user'); inputEl.textContent = ''; setTimeout(() => addMessage('Echo: ' + txt, 'bot'), 200); }); </script> </body> </html>

Answer

I'm not sure this is work or not but you can try once,

To replicate the ChatGPT-like chat viewport behaviour where: Each new user message appears flush at the top of the viewport (pushing older ones up and out of view). New assistant replies are automatically scrolled into view at the bottom. You'll need to: Key Behaviours For user messages: Scroll so the message is at the top of the viewport. For bot messages: Scroll to the bottom to reveal the latest content. CSS Fix (no change needed) Your CSS structure is mostly good, especially with: .chat-messages { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; } JavaScript Fix Update addMessage() to differentiate between user and bot messages and scroll accordingly: function addMessage(text, cls) { const m = document.createElement('div'); m.className = `message ${cls}`; m.textContent = text; // Append the message in order (bottom of container) msgs.appendChild(m); if (cls === 'user') { // Scroll the new user message to the top of viewport // Use scrollTop to position it flush at top const offsetTop = m.offsetTop; msgs.scrollTo({ top: offsetTop, behavior: 'smooth' }); } else { // Scroll to the bottom to reveal latest assistant message msgs.scrollTo({ top: msgs.scrollHeight, behavior: 'smooth' }); } } Resulting Behaviour Each user message appears at the top of the visible area. Bot replies scroll down like a chat window normally does. DOM order remains chronological (appendChild maintains this).

Related Articles