How to create chat bubbles like facebook Messenger - html

How would I create chat bubbles like this. More specifically how to group two ore more consecutive messages by one type of user into a bubble as a whole. For example FOR THE SENDER - the first message has right bottom border a 0, the messages in between have right top,bottom as 0 border radius and the last one has top right 0 border radius . Do I have to use javascript or can it be done using css.
HTML structure ca be
<ul>
<li class="him">By Other User</li>
<li class="me">By this User, first message</li>
<li class="me">By this User, secondmessage</li>
<li class="me">By this User, third message</li>
<li class="me">By this User, fourth message</li>
</ul>
What kind of css class/styles should i be using?

This is a rather basic example but it should explain all of the fundamentals you require.
Most of the solution lies within + adjacent sibling selector. In this case, it's used to apply a different border radius to multiple messages in a row from the same person.
ul{
list-style: none;
margin: 0;
padding: 0;
}
ul li{
display:inline-block;
clear: both;
padding: 20px;
border-radius: 30px;
margin-bottom: 2px;
font-family: Helvetica, Arial, sans-serif;
}
.him{
background: #eee;
float: left;
}
.me{
float: right;
background: #0084ff;
color: #fff;
}
.him + .me{
border-bottom-right-radius: 5px;
}
.me + .me{
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
.me:last-of-type {
border-bottom-right-radius: 30px;
}
<ul>
<li class="him">By Other User</li>
<li class="me">By this User, first message</li>
<li class="me">By this User, secondmessage</li>
<li class="me">By this User, third message</li>
<li class="me">By this User, fourth message</li>
</ul>

You will need a start and a end class, like this
li {
border: 1px solid black;
list-style-type: none;
margin: 2px 0;
padding: 2px 5px;
}
.him {
float: left;
border-radius: 0 10px 10px 0;
clear: both;
}
.me {
float: right;
border-radius: 10px 0 0 10px;
clear: both;
}
.him.start {
border-top-left-radius: 10px;
}
.him.end {
border-bottom-left-radius: 10px;
}
.me.start {
border-top-right-radius: 10px;
}
.me.end {
border-bottom-right-radius: 10px;
}
<ul>
<li class="him start">By Other User</li>
<li class="him">By Other User</li>
<li class="him end">By Other User</li>
<li class="me start">By this User, first message</li>
<li class="me">By this User, secondmessage</li>
<li class="me">By this User, third message</li>
<li class="me end">By this User, fourth message</li>
<li class="him start">By Other User</li>
<li class="him">By Other User</li>
<li class="him end">By Other User</li>
<li class="me start">By this User, first message</li>
<li class="me">By this User, secondmessage</li>
<li class="me">By this User, third message</li>
<li class="me end">By this User, fourth message</li>
</ul>

Here is a pure css solution, but it hinges on your ability to detect and apply the chat__bubble--stop class when the final message of a group is sent. Unfortunately the pseudo class :last-of-type can't be used; as others have pointed out, the last message in a group isn't necessarily the last of the conversation. It also makes use of the adjacent sibling selector (+).
.chat {
list-style-type: none;
width: 20em;
}
.chat__bubble {
margin-bottom: 3px;
padding: 5px 10px;
clear: both;
border-radius: 10px 10px 2px 2px ;
}
.chat__bubble--rcvd {
background: #f2f2f2;
color: black;
float: left;
border-bottom-right-radius: 10px;
}
.chat__bubble--sent {
background: #0066ff;
color: white;
float: right;
border-bottom-left-radius: 10px;
}
.chat__bubble--sent + .chat__bubble--sent {
border-top-right-radius: 2px;
}
.chat__bubble--rcvd + .chat__bubble--rcvd {
border-top-left-radius: 2px;
}
.chat__bubble--stop {
border-bottom-right-radius: 10px;
border-bottom-left-radius: 10px;
}
<ul class="chat">
<li class="chat__bubble chat__bubble--rcvd chat__bubble--stop">What are you up to?</li>
<li class="chat__bubble chat__bubble--sent">Not much.</li>
<li class="chat__bubble chat__bubble--sent">Just writing some CSS.</li>
<li class="chat__bubble chat__bubble--sent">I just LOVE writing CSS.</li>
<li class="chat__bubble chat__bubble--sent chat__bubble--stop">Do you?</li>
<li class="chat__bubble chat__bubble--rcvd">Yeah!</li>
<li class="chat__bubble chat__bubble--rcvd">It's super fun.</li>
<li class="chat__bubble chat__bubble--rcvd chat__bubble--stop">... SUPER fun.</li>
</ul>

I would suggest following this article for help when it comes to creating text bubbles:
https://www.templatemonster.com/blog/chat-bubbles-css-ui-tutorial/
As for the beginning and ending bubbles, use JQuery to identify and change their CSS properties based on their parent container.
if you want the sent images, you will need to wrap them inside of the li and do a float right, or absolute position inside of a relative object (the li).
<ul class="ulContainer">
<li>test1</li>
<li>test1</li>
<li>test1</li>
</ul>
Css:
.ulContainer li{
width:200px;
height:20px;
background-color:#9abff9;
list-style-type:none;
margin:10px 0 10px 0;
padding: 3px 3px 3px 5px;
border-radius: 10px 2px 2px 10px;
}
Use below script to change first and last li:
$('.ulContainer li:first').css('border-top-right-radius','10px');
$('.ulContainer li:last').css('border-bottom-right-radius','10px');
here's the JSFiddle: https://jsfiddle.net/s60dgfw2/
Update based upon your comment:
I believe this is the closest you can get to what you are trying to achieve without using JQuery. You need advanced selectors you can only get from grouping in .each() statements through JQuery. Or by adding multiple css classes to Lists.
Please see the response by LGSon's for how to do it with multiple CSS classes.
Or see below:
https://jsfiddle.net/5dcto0td/
.fancyContainer{
border: 1px solid #555;
position:relative;
width:300px;
padding:5px;
overflow:hidden;
}
.chatBox {
width: 300px;
list-style: none;
margin: 0 0 0 -40px;
position:0;
}
.chatBox li {
margin: 5px 0 5px 0;
padding: 3px 5px 3px 5px;
}
/*Set up initial chat element for .me*/
.chatBox .me {
min-height: 20px;
float:right;
clear: both;
background-color: #34a1ef;
border-radius: 10px 2px 2px 10px;
}
/*Set up initial chat element for .him*/
.chatBox .him {
min-height: 20px;
float:left;
clear: both;
background-color: #ddd;
border-radius: 2px 10px 10px 2px;
}
/*Set up grouped radius*/
.him + .me {
border-top-right-radius:10px;
}
.me + .him {
border-top-left-radius:10px;
}
.me + .me {
border-bottom-right-radius:2px;
}
.him + .him {
border-bottom-left-radius:2px;
}
/*Set up First and Last radius for .me*/
.chatBox > .me:first-child {
border-top-right-radius:10px;
}
.chatBox > .me:last-child{
border-bottom-right-radius:10px;
}
/*Set up First and Last radius for .him*/
.chatBox > .him:first-child{
border-top-left-radius:10px;
}
.chatBox > .him:last-child{
border-bottom-left-radius:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="fancyContainer">
<ul class="chatBox">
<li class="him">Hello... This is a chatbox.</li>
<li class="me">Well well. I guess this is a chatbox.</li>
<li class="me">I'll have to talk about this some other time.</li>
<li class="me">No wait. I might change my mind</li>
<li class="him">Nonesense good sir! We'll have this talk right now and here.</li>
<li class="him">I Like...</li>
<li class="him">popsicles.</li>
<li class="me">I can't believe you've done this to me!</li>
</ul>
</div>

Related

How to remove empty space between <ul>s, with list-group-horizontal (boostrap 4)?

I'm working on a small project for school.
I'm printing results from a database, and I put the data into 3 different 'list-group-item', and every row of data is in a different .
So, it's an ul for every row (and I have to print a lot of them).
The problem is the space between every , and I'm really getting crazy.
I tried everything found on the internet, but really can't resolve my problem.
I'd like that the spaces between the different rows to totally disappear.
Thanks to anyone :)
.list-group-horizontal {
margin: 0;
padding: 0;
}
.list-group-horizontal .list-group-item {
display: inline-block;
margin-bottom: 0;
margin-left:-4px;
margin-right: 0;
border-right-width: 0;
width: 33%;
height: 55px;
overflow: auto;
text-align: center;
overflow-y: hidden;
white-space: nowrap;
border: 1px solid #d00;
}
.list-group-horizontal .list-group-item:first-child {
border-top-right-radius:0;
border-bottom-left-radius:4px;
}
.list-group-horizontal .list-group-item:last-child {
border-top-right-radius:4px;
border-bottom-left-radius:0;
border-right-width: 1px;
}
<ul class="list-group-horizontal">
<li class="list-group-item">Nome Libro</li>
<li class="list-group-item">Data Prestito</li>
<li class="list-group-item">Data Riconsegna</li>
</ul>
<ul class="list-group-horizontal">
<li class="list-group-item">I Robot</li>
<li class="list-group-item">2018-01-19 03:14:07</li>
<li class="list-group-item">2019-01-19 03:14:07</li>
</ul>
.list-group-horizontal {
margin: 0;
padding: 0;
}
.list-group-horizontal .list-group-item {
display: inline-block;
margin-bottom: 0;
margin-left:-4px;
margin-right: 0;
border-right-width: 0;
width: 33%;
height: 55px;
overflow: auto;
text-align: center;
overflow-y: hidden;
white-space: nowrap;
border: 1px solid #d00;
}
.list-group-horizontal .list-group-item:first-child {
border-top-right-radius:0;
border-bottom-left-radius:4px;
}
.list-group-horizontal .list-group-item:last-child {
border-top-right-radius:4px;
border-bottom-left-radius:0;
border-right-width: 1px;
}
<ul class="list-group-horizontal">
<li class="list-group-item">Nome Libro</li>
<li class="list-group-item">Data Prestito</li>
<li class="list-group-item">Data Riconsegna</li>
</ul>
<ul class="list-group-horizontal">
<li class="list-group-item">Nome Libro</li>
<li class="list-group-item">Data Prestito</li>
<li class="list-group-item">Data Riconsegna</li>
</ul>

how to set a font size and padding percentage to be equal each boxes?

I did some research with font size and boxes sizes. I created ul li and styling them with some CSS to make them looks like a table and stay inline. after the epic code i realize that each words are different like home, tutorial, contact us, and registration. all font have a different sizes and different paddings to use.
so this is my code...
i tidy this up so it's not looks like in my localhost. what i did was made the percentage like 3.5754% to set the padding to get the exact SAME width of the boxes. so 4 of them should be the same size of boxes.
at home i created padding like 5% or so.
at tutorial i created padding like 3.something%
and etc.
because each words has a different width and number of letters.
sorry for my English, please let me know if i'm confusing u guys..
but please help about this percentage and font thing. i really don't get it. if u guys have some article to read it's also help... because i'm still looking for it. ty guys :)
body {
margin: 0;
padding: 0;
}
.navigation {
top: 0;
width: 90%;
height: 120px;
background: #ccc;
margin: 0 auto;
text-align: center;
}
.nav-head {
padding-top: 5%;
padding-left: 0;
width: 100%;
margin:
/*0 7.2%*/
;
}
.nav a {
color: #e74c3c;
text-decoration: none;
font-size: 1em;
}
.nav {
list-style: none;
display: inline;
border: solid 1px #e74c3c;
margin-left: 0;
}
#nav1 {
padding: 1% 1%;
}
#nav2 {
padding: 1% 5.74%;
}
#nav3 {
padding: 1% 3%;
}
#nav4 {
padding: 1% 3%;
}
.nav:hover {
padding: 2.2% 5%;
border: solid 1px #e74c3c;
}
.nav.currentpage {
padding: 2.2% 5%;
border: solid 1px #e74c3c;
}
<nav class="navigation">
<ul class="nav-head">
<li class="nav" id="nav1">HOME
</li>
<li class="nav" id="nav2">REGISTRATION
</li>
<li class="nav" id="nav3">TUTORIAL
</li>
<li class="nav" id="nav4">CONTACT US
</li>
</ul>
</nav>
2 easy option I believe:
1) display:table + table-layout:fixed;
body {
margin: 0;
padding: 0;
}
.navigation {
width: 90%;
height: 120px;
background: #ccc;
margin: 0 auto;
text-align: center;
}
.nav-head {
display:table;
width:100%;
padding:0;
table-layout:fixed;
}
.nav a {
color: #e74c3c;
text-decoration: none;
font-size: 1em;
}
.nav {
display:table-cell;
border: solid 1px #e74c3c;
}
#nav1 {
}
#nav2 {
}
#nav3 {
}
#nav4 {
}
.nav:hover {
border: solid 1px ;
}
.nav.currentpage {
border: solid 1px ;
}
<nav class="navigation">
<ul class="nav-head">
<li class="nav" id="nav1">HOME
</li>
<li class="nav" id="nav2">REGISTRATION
</li>
<li class="nav" id="nav3">TUTORIAL
</li>
<li class="nav" id="nav4">CONTACT US
</li>
</ul>
</nav>
2) display:flex + flex:1;
body {
margin: 0;
padding: 0;
}
.navigation {
width: 90%;
height: 120px;
background: #ccc;
margin: 0 auto;
text-align: center;
}
.nav-head {
display:flex;
padding:0;
list-style-type:none;
}
.nav a {
color: #e74c3c;
text-decoration: none;
font-size: 1em;
}
.nav {
flex:1;
border: solid 1px #e74c3c;
}
#nav1 {
}
#nav2 {
}
#nav3 {
}
#nav4 {
}
.nav:hover {
border: solid 1px ;
}
.nav.currentpage {
border: solid 1px ;
}
<nav class="navigation">
<ul class="nav-head">
<li class="nav" id="nav1">HOME
</li>
<li class="nav" id="nav2">REGISTRATION
</li>
<li class="nav" id="nav3">TUTORIAL
</li>
<li class="nav" id="nav4">CONTACT US
</li>
</ul>
</nav>
Using percentages is not always the best idea, specially for padding. Instead, use min-width, a normal padding and control the gutter with font-size:0 on the parent and normal padding on the LIs
Here is the code:
.nav-head{
font-size:0;
}
.nav {
padding: 2px 5px !important;
min-width: 116px;
display: inline-block;
margin: 0 !important;
font-size: 15px;
border:1px solid red;
}
And here is the DEMO
Here is the explanation on the font-zero concept link
You can use Flexbox to help you in making all the items with same width.
body {
margin: 0;
padding: 0;
}
.navigation {
top: 0;
width: 90%;
height: 120px;
background: #ccc;
margin: 0 auto;
text-align: center;
}
.nav-head {
display: flex;
padding-top: 5%;
padding-left: 0;
width: 100%;
}
.nav a {
color: #e74c3c;
text-decoration: none;
font-size: 1em;
}
.nav {
list-style: none;
flex: 1;
border: solid 1px #e74c3c;
margin-left: 0;
padding-top: 2.2%;
padding-bottom: 2.2%;
}
.nav:hover {
border: solid 1px #e74c3c;
}
.nav.currentpage {
padding-top: 2.2%;
padding-bottom: 2.2%;
border: solid 1px #e74c3c;
}
<nav class="navigation">
<ul class="nav-head">
<li class="nav" id="nav1">HOME
</li>
<li class="nav" id="nav2">REGISTRATION
</li>
<li class="nav" id="nav3">TUTORIAL
</li>
<li class="nav" id="nav4">CONTACT US
</li>
</ul>
</nav>

CSS - nth-child conditions appearing on wrong elements

The goal is a rounded side nav with hover effects in CSS. I'm using nth-child to control border radius for the top and bottom. As you will see on the fiddle, when you hover over the elements in between the 1st and 4th child, you get the radius settings of nth-child(1). Why?
I'm using this markup:
http://jsfiddle.net/hKxt9/
HTML
<ul id="side-nav">
<li class="side-nav-item clients" id="link_clients">Clients</li>
<li class="side-nav-item rtemplates" id="link_routine_templates">Routines</li>
<li class="side-nav-item exlib" id="link_exercise_library">Exercise Library</li>
<li class="side-nav-item logout" id="link_log_out">Log Out</li>
</ul>
CSS
#side-nav{
border: 1px solid #D5D5D5;
border-radius: 10px;
padding: 0px !important;
list-style-type: none;
}
.side-nav-item{
padding: 10px;
border-bottom: 1px solid #D5D5D5;
border-radius: 0;
margin: 0px !important;
font-size: 16px;
font-weight: bold;
}
.side-nav-item a{
color: #808080;
}
.side-nav-item:hover{
background: #D5D5D5;
}
.side-nav-item.active{
background: #01bbea;
}
.side-nav-item.active {
color: #fff;;
}
.side-nav-item:nth-child(4){
border-bottom: 0px solid black;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
}
.side-nav-item:nth-child(1){
border-top-left-radius: 10px;
border-top-right-radius: 10px;
border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px;
border-bottom: 1px solid #D5D5D5;
}
First of all it is wrong to have anchors as child nodes of a list. You structure should look like ul>li>a.
On the other hand nth-child() works for elements, not for class selectors. And even not being so, your elements with .side-nav-item class are always the first element of its father, which are always the anchor. So if nth-child() would work for classes (which is not the case) then your code wouldn't work anyway.
So if you change your structure to this:
<ul>
<li></li>
<li></li>
<li></li>
</ul>
Which is valid HTML, then you can do what you are looking for in this way:
li:nth-child(1) a {
/* your stylings */
}

CSS Ul li navigation issue: Can't get correct result

Trying to get following result when I hover
for markup below
<ul>
<li>Current Month</li>
<li>Current Week</li>
<li>Previous Month</li>
<li>Previous Week</li>
<li>Next Month</li>
<li>Next Week</li>
<li>Team Calendar</li>
<li>Private Calendar</li>
<li>Settings</li>
</ul>
Can't figure out solution using CSS3 border-radius. Any suggestions?
Update
Please don't post dotted lists. I need solution for arrowed list.
It's not same thing: when you use arrow, you need to set it as background-image of li.
There is another way, to set arrow as a bullet picture, but this time you have no way to control gap between arrow and link.
li:hover {
background-color:#e4e4e4;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
jsfiddle
EDIT
If you want to use arrows instead, just use the :before pseudo element.
ul {
list-style-type:none;
}
li {
padding:5px;
}
li:hover {
width:100px;
background-color:#e4e4e4;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
li:before {
content:"> ";
}
updated jsFiddle
Just replace the > with your image.
EDIT 2
To have the background only over the text, just add that style to the link instead of the li then.
http://jsfiddle.net/SEzxP/2/
EDIT 3
To use an image instead, just use url() after content
li:before { content:url('http://www.nationalacademies.org/xpedio/groups/system/documents/webgraphics/na_right_arrow.gif') /* with class ModalCarrot ??*/
}
Updated jsFiddle
<style>
.my-list li a{
text-decoration:none;
color:#000;
}
.my-list li a:hover
{
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
text-decoration: none;
background-color: #e4e4e4;
}
.my-list li{
list-style-image:url(http://www.nationalacademies.org/xpedio/groups/system/documents/webgraphics/na_right_arrow.gif)
}
</style>
<ul class="my-list">
<!--Example of gap using whitespace-->
<li> Current Month</li>
<!--Example of a gap using padding for finer control of desired gap-->
<li><a style="padding-left:20px;" href="#">Current Week</a></li>
<li>Previous Month</li>
<li>Previous Week</li>
<li>And so on...</li>
</ul>
See jsFiddle also: http://jsfiddle.net/KRaJN/3/
Something like this?
jsFiddle here
CSS
ul {
list-style:none;
background:#E6E6E6;
border-left:3px solid rgb(0, 194, 255);
}
li a {
text-decoration:none;
color:black;
}
li a:hover {
border-radius:5px;
background: #cacaca;
}
li:before {
content:"►";
font-size:10px;
margin-right:10px;
}
body {
background-color: #F3F3F3;
}
ul {
list-style: none;
margin: 0;
padding: 0;
font-family: Arial, Tahoma;
font-size: 13px;
border-left: 1px solid #4AFFFF;
padding-left: 10px;
}
li {
margin: 0;
padding: 0;
}
li:before {
content: " ";
display:inline-block;
border-style: solid;
border-width: 5px 0 5px 5px;
border-color: transparent transparent transparent #000000;
}
li a {
margin-left: 5px;
display: inline-block;
border-radius: 3px;
color: #000;
padding: 3px 5px;
text-decoration: none;
width: 150px;
}
li a:hover {
background-color: #DBDBDB;
font-weight: bold;
}
This should be ezactly how you want it!
http://jsfiddle.net/2JJaW/

CSS: Only part of my menu are supposed to hide

I'm trying to hide part of my menu. When I call display:none The entire menu disappears. I have id's to separate them so I don't get why this happens. Here's the code:
HTML:
<ul id="menu">
<li>Categories 1
<ul id="cat1">
<li>temp1</li>
<li>temp2</li>
<li>temp3</li>
</ul>
</li>
</ul>
CSS:
#menu {
background-color: #0000FF;
height: 20px;
padding: 15px 0 10px;
margin-bottom: 20px;
font: 12px 'DroidSansBold', Tahoma,sans-serif;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
box-shadow: 3px 2px 3px #000;
border-radius: 5px;
text-align: center;
}
#menu li{
display: inline-block;
}
#menu li a {
color: #fff;
text-decoration: none;
margin: 0 120px;
}
#cat1 li{
display: block;
padding: 10px;
}
#cat1 li a{
background-color: #0000FF;
padding: 10px;
border-radius: 5px;
}
Somewhat working demo: http://jsfiddle.net/ZfN7t/
When you're dealing with ul inside ul, it's usually easier to style if you give them different classes:
<ul id="menu">
<li class="menu-item">Categories 1
<ul id="cat1">
<li class="cat1-item">temp1</li>
<li class="cat1-item">temp2</li>
<li class="cat1-item">temp3</li>
</ul>
</li>
</ul>
Hide the temp1, temp2, temp3 like this:
.menu-item #cat1{
display:none;
}
To display on hover:
.menu-item:hover #cat1{
display:block;
}