CSS3 Chat Bubbles with Flex
by Leandro Barbosa
HTML
<div class="wrap">
<div id="chatWindow" class="container">
<div class="bubble left">
<p>msg</p>
</div>
<div class="bubble left">
<p>long message</p>
</div>
<div class="bubble right">
<p>ultra long message which can wrap at eighty percent long message which can wrap at eighty percent </p>
</div>
<div class="bubble left">
<p>lorem ipsum</p>
</div>
<div class="bubble right">
<p>very long message</p>
</div>
<div class="bubble right">
<p>one more message</p>
</div>
<div class="bubble left">
<p>lorem ipsum</p>
</div>
<div class="bubble right">
<p>another message</p>
</div>
<div class="bubble left">
<p>lorem ipsum</p>
</div>
<div class="bubble right">
<p>yet another message</p>
</div>
<div class="bubble left">
<p>lorem ipsum</p>
</div>
</div>
<div id="inputWindow" class="form">
<input id="inp" type="text" />
<div>
<input id="btn" type="button" value="Send" />
</div>
</div>
</div>
SCSS
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
overflow: hidden;
}
.wrap {
padding: 15px;
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
}
.container {
flex: 1 1 90%;
display: flex;
flex-direction: column-reverse;
background-color: #eee;
border: 1px solid red;
overflow: auto;
}
.form {
flex: 0 0 10%;
display: flex;
border: 1px solid blue;
max-height: 32px;
input[type=text] {
flex: 1 1 auto;
border: 1px solid #eee;
}
input[type=button] {
flex: 0 0 20%;
border: 1px solid #eee;
}
}
.bubble {
flex: 1 1 auto;
clear: both;
p {
border-radius: 5px;
padding: 8px;
margin: 8px 12px;
max-width: 80%;
position: relative;
transition: background-color 0.5s;
}
&.left p {
background-color: #ccc;
float: left;
&::before {
content: '';
position: absolute;
width: 0;
height: 0;
left: -8px;
top: 8px;
border-top: 4px solid transparent;
border-right: 8px solid #ccc;
border-bottom: 4px solid transparent;
}
}
&.right p {
background-color: #33c;
color: #fff;
float: right;
&::after {
content: '';
position: absolute;
width: 0;
height: 0;
right: -8px;
bottom: 8px;
border-top: 4px solid transparent;
border-left: 8px solid #33c;
border-bottom: 4px solid transparent;
}
}
}
JavaScript
var btn = document.getElementById('btn'),
inp = document.getElementById('inp'),
chats = document.getElementById('chatWindow');
btn.addEventListener('click', postMsg);
inp.addEventListener('keyup', function(e) {
if (e.keyCode == 13) {
postMsg();
}
});
function postMsg() {
var msg = inp.value,
bubble = document.createElement('div'),
p = document.createElement('p');
if (msg.trim().length <= 0) {
return;
}
bubble.classList.add('bubble');
bubble.classList.add('right');
p.textContent = msg;
bubble.append(p);
inp.value = '';
chats.insertBefore(bubble, chats.firstChild);
rcvdMsg();
}
function rcvdMsg() {
var msg = "what?",
bubble = document.createElement('div'),
p = document.createElement('p');
if (msg.trim().length <= 0) {
return;
}
bubble.classList.add('bubble');
bubble.classList.add('left');
p.textContent = msg;
bubble.append(p);
chats.insertBefore(bubble, chats.firstChild);
}