Create CSS3 Speech Bubbles Without Images

5:48:00 PM |

CSS3 is starting to change our lives for the better. It’s now possible to create a great looking speech bubble which works in all browsers, uses a single HTML element, a few lines of CSS3 code, no images, and no JavaScript whatsoever…
CSS3 speech bubble
To ease you in gently, let’s examine the HTML. A single element is required, so I’m using a P tag:
  1. <p class="speech">SitePoint Rocks!</p>  
First, we’ll style the outer box:
  1. p.speech  
  2. {  
  3.     position: relative;  
  4.     width: 200px;  
  5.     height: 100px;  
  6.     text-align: center;  
  7.     line-height: 100px;  
  8.     background-color: #fff;  
  9.     border: 8px solid #666;  
  10.     -webkit-border-radius: 30px;  
  11.     -moz-border-radius: 30px;  
  12.     border-radius: 30px;  
  13.     -webkit-box-shadow: 2px 2px 4px #888;  
  14.     -moz-box-shadow: 2px 2px 4px #888;  
  15.     box-shadow: 2px 2px 4px #888;  
  16. }  
Nothing too complicated there. The only essential property is position: relative which is necessary for the speech bubble pointer. We also require Mozilla and Webkit vendor prefixes for border-radius and box-shadow to ensure they work in all CSS3 browsers. IE8 and below will show squared corners and no shadow, but the box will still be visible.
CSS3 speech bubble
Now we need to create the triangular bubble pointer. Rather than resorting to images, we can use CSS borders to create any type of triangle. As a brief explanation, examine an element with wide differently-colored borders:
CSS3 border triangles
If we reduce the width and height of our element to 0px and use different sized borders, we can see different triangles being formed:
CSS3 border triangles
For our speech bubble pointer, we can therefore use a solid top and left border with transparent right and bottom borders:
CSS3 border triangles
But what do we assign those border properties to? Fortunately, we can use the CSS :before and :afterpseudo-elements to generate two more content items. Therefore:
  1. p.speech:before  
  2. {  
  3.     content: ' ';  
  4.     position: absolute;  
  5.     width: 0;  
  6.     height: 0;  
  7.     left: 30px;  
  8.     top: 100px;  
  9.     border: 25px solid;  
  10.     border-color: #666 transparent transparent #666;  
  11. }  
The triangle is positioned at the bottom of our bubble. Incidentally, don’t bother trying to apply a shadow to this element — it’ll be shown around the transparent borders rather than the visible triangle.
CSS3 speech bubble
We must now remove a section of this triangle. We can position a smaller white triangle over the gray one to achieve that effect:
  1. p.speech:after  
  2. {  
  3.     content: ' ';  
  4.     position: absolute;  
  5.     width: 0;  
  6.     height: 0;  
  7.     left: 38px;  
  8.     top: 100px;  
  9.     border: 15px solid;  
  10.     border-color: #fff transparent transparent #fff;  
  11. }  
Our pure CSS3 image-less speech bubble is complete.
CSS3 speech bubble
In essence, we can utilize the :before and :after pseudo-elements to create many different effects. For example, a thought bubble can be created with two content items rounded into circles.
  1. p.thought  
  2. {  
  3.     position: relative;  
  4.     width: 130px;  
  5.     height: 100px;  
  6.     text-align: center;  
  7.     line-height: 100px;  
  8.     background-color: #fff;  
  9.     border: 8px solid #666;  
  10.     -webkit-border-radius: 58px;  
  11.     -moz-border-radius: 58px;  
  12.     border-radius: 58px;  
  13.     -webkit-box-shadow: 2px 2px 4px #888;  
  14.     -moz-box-shadow: 2px 2px 4px #888;  
  15.     box-shadow: 2px 2px 4px #888;  
  16. }  
  17. p.thought:before, p.thought:after  
  18. {  
  19.     left: 10px;  
  20.     top: 70px;  
  21.     width: 40px;  
  22.     height: 40px;  
  23.     background-color: #fff;  
  24.     border: 8px solid #666;  
  25.     -webkit-border-radius: 28px;  
  26.     -moz-border-radius: 28px;  
  27.     border-radius: 28px;  
  28. }  
  29. p.thought:after  
  30. {  
  31.     width: 20px;  
  32.     height: 20px;  
  33.     left: 5px;  
  34.     top: 100px;  
  35.     -webkit-border-radius: 18px;  
  36.     -moz-border-radius: 18px;  
  37.     border-radius: 18px;  
  38. }  
CSS3 thought bubble