I searched very long time how to auto scroll chat without JavaScript
. But coludn't find any solution except this example but there the scroll with mouse not works as expected. Anyway all the others uses JavaScript
more or less. But after some time I saw at an employee one a strange (because I don't clearly understand why it works) but simple solution and I want to share it with SO community. May be someone also search how to auto scroll only with CSS
properties and HTML
.
CodePudding user response:
The "magic" part is in the .messages-wrapper
. All we need in generally is just wrap our .messages
to another div
and set to it flex-direction: column-reverse
. Also we can control from where messages will start from top or from bottom just adding/removing height: 100%
property to .messages-wrapper
. The part which I don't understand is why the column-reverse
works? I always saw that column-reverse
reverse only first level children order but in this case it do some "magic". I will very glad if someone explains me how and why it works
//JUST TO ADD MESSAGES DYNAMICALLY
const topMessages = document.querySelector('.start-from-top .messages');
const bottomMessages = document.querySelector('.start-from-bottom .messages');
let topMessagesNumber = 0;
let bottomMessagesNumber = 0;
const addMessage = (messages, number) => {
const message = document.createElement('div');
message.innerHTML = 'Some text ' number;
message.className = 'message';
const isRightMessage = Math.random() >= 0.5;
message.classList.add(`${isRightMessage ? 'right' : 'left'}`);
messages.append(message);
}
const addTopMessage = () => {
addMessage(topMessages, topMessagesNumber);
}
const addBottomMessage = () => {
addMessage(bottomMessages, bottomMessagesNumber);
}
div:not(.messages):not(.messages-wrapper) {
outline: 1px solid black;
}
.chat {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 150px;
}
.messages-wrapper {
display: flex;
flex-direction: column-reverse;
overflow-y: auto;
}
.messages-wrapper.start-from-bottom {
height: 100%;
}
.message {
margin: 16px 8px;
}
.message.right {
text-align: right;
}
.message.left {
text-align: left;
}
.add-message {
padding: 8px;
}
Starting first message from top
<div >
<div >
<div ></div>
</div>
<div >
<button onclick="addTopMessage()">Add message</button>
</div>
</div>
<br>
<br>
Starting first message from bottom
<div >
<div >
<div ></div>
</div>
<div >
<button onclick="addBottomMessage()">Add message</button>
</div>
</div>
CodePudding user response:
In order to achieve that functionality you need to put scrollTop
equal to scrollHeight
$(function () {
$('form').on('submit', function (event) {
event.preventDefault();
var message = $('.message').first().clone();
message.find('p').text($('input').val());
message.prependTo('.chat-container');
$('input').val('');
/* FOR AUTO SCROLL TO BOTTOM */
$('.chat-container').scrollTop = $('.chat-container').scrollHeight;
});
});
* {
box-sizing: border-box;
}
.container {
width: 400px;
margin: 0 auto;
border: solid 1px #ccc;
border-radius: 5px;
overflow: hidden;
}
.chat-container {
max-height: 400px;
overflow: auto;
transform: rotate(180deg);
direction: rtl;
}
.chat-container .message {
border-bottom: solid 1px #ccc;
padding: 20px;
transform: rotate(180deg);
direction: ltr;
}
.chat-container .message .avatar {
float: left;
margin-right: 5px;
}
.chat-container .message .datetime {
float: right;
color: #999;
}
.send-message-form input {
width: 100%;
border: none;
font-size: 16px;
padding: 10px;
}
.send-message-form button {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
<div >
<div >
<img src="https://placeimg.com/50/50/people?1">
<div >23/03/2016 20:40</div>
<p>A message text</p>
</div>
<div >
<img src="https://placeimg.com/50/50/people?2">
<div >23/03/2016 20:40</div>
<p>A message text</p>
</div>
<div >
<img src="https://placeimg.com/50/50/people?1">
<div >23/03/2016 20:40</div>
<p>A message text</p>
</div>
</div>
<form >
<input type="text" placeholder="Ciao">
<button type="submit">Send</button>
</form>
</div>
And also instead of height: 400px
change it to max-height: 400px;
and then set overflow-y: auto
.
NOTE FOR BETTER VIEW CHECK IT IN full screen or CODEPEN.