Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Facebook Chatheads in CSS

DZone's Guide to

Facebook Chatheads in CSS

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

fb-ch-single

If you haven’t seen Facebook’s “chat head” interface, here is the quick lowdown. The are little circular icons that will float on the side of your mobile device’s screen to tell you that a message has arrives from a friend. It’s part of the Facebook Home thing, but even if you are on iOS, the Facebook App uses them.  I think this will be one of those UI things you either love or hate.

However, from an HTML angle, I thought they were interesting. Could you do this interface in HTML/CSS.  The answer is yes, and it is quite easy. Just some borders, border-padding and negative margin.


<!DOCTYPE html> 
<html> 
<head> 
  <title>Practical CSS - Single Chathead</title>
      <link rel="stylesheet" href="css/single.css" type="text/css" media="screen" />
</head> 
<body>

<img src="img/tpryan.png" class="chathead">

<div class="content">
	<h2>The Main Thing</h2>
	<p>DIY ea nulla photo booth tempor occaecat, velit nihil mixtape scenester. 
      Irony laboris echo park, wolf officia vice cupidatat labore butcher freegan 
      farm-to-table nisi velit aliqua gluten-free. Aliquip nesciunt assumenda, 
      wayfarers seitan wolf reprehenderit nulla twee sartorial dolore food truck 
      voluptate ex vinyl. Aliquip ex enim, irony terry richardson trust fund consectetur 
      fap pariatur dolor. Lo-fi nulla whatever mlkshk, banksy american apparel carles 
      adipisicing incididunt wolf photo booth hipster. Wayfarers four loko ex cosby sweater, 
      adipisicing sartorial non cardigan craft beer cillum reprehenderit terry richardson 
      3 wolf moon mollit. Ethical ut labore beard, 3 wolf moon duis readymade assumenda 
      hipster tofu mcsweeney's master cleanse.</p>
      <p>Irony mixtape cupidatat 3 wolf moon, id cardigan retro cillum exercitation 
      biodiesel wes anderson locavore. Voluptate vinyl lo-fi, ethical sunt et irure nihil 
      fugiat. Terry richardson tumblr art party, artisan quis est cillum messenger bag 
      officia duis. Elit cliche letterpress est, single-origin coffee wayfarers mustache 
      aesthetic esse echo park dolor synth yr viral artisan. Do vinyl terry richardson 
      officia food truck. Veniam cupidatat et aliquip. Sartorial tattooed tofu odio eu 
      culpa ex, irony PBR.</p>
</div>
</body>
</html>
.chathead{
    width: 150px;
    height: 150px;
    border-radius: 75px;
    border: 4px solid #FFFFFF;
    box-shadow: 1px 1px 5px rgba(0,0,0,.5);
    position: absolute;
    right: -10px;
} 
fb-ch-single-ss

Demo

That was relatively simple, but it gets more complex when you have a multi-person conversation. Facebook takes the most recent person in the thread and makes them take up half of the “chat head.” Then come the next two, taking up a quarter each.  Then the rest are hidden.

Okay, so I need to pull out of n-th child magic to selectively style the first 3 items in a collection of images. Set overflow to hidden, play with some more border radii and BOOM, “chat heads” done.

<div class="chathead-multiple">
  <img src="img/tpryan.png">
  <img src="img/jonesbey.png">
  <img src="img/mcorlan.png">
  <img src="img/khoyt.png">
</div> 

.chathead-multiple{
      width: 150px;
      height: 150px;
      border-radius: 75px;
      border: 4px solid #FFFFFF;
      box-shadow: 1px 1px 5px rgba(0,0,0,.5);
      right: -10px;
      overflow: hidden;
      position: absolute;
      margin-right: -10px;
      z-index: 10;

}

.chathead-multiple img{
      display: none;
      margin: 0;
      z-index: 1;
}

.chathead-multiple img:nth-child(-n+3) {
   width: 75px;
   height: 75px;
   display: inline-block;
   position: absolute;
}

.chathead-multiple img:first-child {
   width: 150px;
   height: 150px;
   left: -75px;
   border-right: 1px solid #FFFFFF;
}


.chathead-multiple img:nth-child(2) {
   left: 75px;
   top:0;
   border-bottom: 1px solid #FFFFFF;
   border-left: 1px solid #FFFFFF;
   border-radius: 0 75px 0  0;
}

.chathead-multiple img:nth-child(3) {
   left: 75px;
   bottom:0;
   border-top: 1px solid #FFFFFF;
   border-left: 1px solid #FFFFFF;
   border-radius: 0 0 75px 0;
}

fb-ch-multi-ss

Demo

Okay, so that’s all been pretty straight forward, so I’d like them to be interactive.  If I click on a multi member conversation “chat head” I’d like it to expand out the rest of the members. This is very easy. Just a little Javascript and some class swapping.


Demo

So done, Facebook native interface done in CSS/HTML.  But I think we can do better.  One of my issues about this interface and one that would prevent me from using it in a web based application is that it obscures the content beneath it, it just hangs out covering up anything unfortunate to be below it. For me, if I was using it I would want it to float instead of absolutely position. So I can do a few tweaks to make that happen.

h2{
      clear: both;
}

.content{
   text-align: right;
}

.chathead-multiple{
      float: right;
      width: 150px;
      height: 150px;
      border-radius: 75px;
      border: 4px solid #FFFFFF;
      box-shadow: 1px 1px 5px rgba(0,0,0,.5);
      overflow: hidden;
      position: relative;
      z-index: 10;
      -webkit-shape-outside: circle(50%, 50%, 60%);  
}

.chathead-multiple img{
      display: none;
      margin: 0;
      z-index: 1;
}

.chathead-multiple img:nth-child(-n+3) {
   display: block;
   width: 75px;
   height: 75px;
   display: inline-block;
   position: absolute;
}

.chathead-multiple img:first-child {
   width: 150px;
   height: 150px;
   left: -75px;
   border-right: 1px solid #FFFFFF;
}
.chathead-multiple img:nth-child(2) {
   left: 75px;
   top:0;
   border-bottom: 1px solid #FFFFFF;
   border-left: 1px solid #FFFFFF;
   border-radius: 0 75px 0  0;
}
.chathead-multiple img:nth-child(3) {
   left: 75px;
   bottom:0;
   border-top: 1px solid #FFFFFF;
   border-left: 1px solid #FFFFFF;
   border-radius: 0 0 75px 0;
}

.chathead-single{
    width: 150px;
    height: 150px;
    border-radius: 75px;
    border: 4px solid #FFFFFF;
    box-shadow: 1px 1px 5px rgba(0,0,0,.5);
    position: relative;
    float: right;
    clear: right;
    margin-left: 65px; 
    margin-bottom: 25px;
    right: 50px;
    /* CANARY ONLY FEATURE NOW    */
    -webkit-shape-outside: circle(50%, 50%, 60%);  
}   



fb-ch-multi-x-float-ss

Demo

Now in my demonstration, I pulled the text to be right aligned instead of left aligned, to show the float edge better.  But I’m still not happy with it. Why? Cause each of those circles carve a giant square out of the text. And that’s kinda lame because they’re circles.  A few weeks ago a colleague of mine at Adobe, Bem Jones-Bey wrote an article about using shaped exclusions from the CSS Shapes and Exclusion spec.  It seemed like a perfect fit.  So if you have Chrome Canary installed, and the experimental features turned on, you get a much different result:

fb-ch-multi-x-float-canary-ss

Demo [View in Canary]

The secret sauce here being the -webkit-shape-outside property.  It basically allows me to exclude a circle from the underlying text around each of the “chat heads”. To find out more about using shape-outside, be sure to check out Bem’s article. It’s just one of the ways that the browser is becoming more capable of rendering a greater number of visual layouts and effects.  

Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.

Topics:

Published at DZone with permission of Terrence Ryan, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}