How to Make a CSS Speech Bubble With a Drop Shadow

What we will be making:

CSS speech bubbles aren’t new, but they are often flat and ugly. Below I will share some tech­niques to improve upon the design and add a seam­less drop shad­ow. It is pos­sible that you are famil­i­ar with many or all of the tech­niques used, if that is the case I would love for you to share an example of when you have had to use some out­side of the box CSS. Before you read on click here to load jsFiddle in a new tab.

The Plan:

Step 1: Write the Markup

The markup for this is very simple. We are going to wrap our text in a span with a class of bubble.

<span class="bubble">Speech bubble with a shadow</span>

Step 2: Basic styling

Now let’s get the basic styl­ing out of the way. This will include choos­ing a back­ground col­or for the bubble, giv­ing it some font styl­ing and also some pad­ding. I like to order the prop­er­ties alpha­bet­ic­ally.

If you look care­fully at the code above you will notice that only white is being used, with the trans­par­ency fad­ing out from 0.5 to 0. This enables us to keep our code easy to edit; if you want to change the col­or of the bubble you only have to alter a single value. Now that our but­ton has some depth lets add a 1px high­light to the top. We can do this using an inset box-shadow.

box-shadow: inset 0 1px 1px hsla(0,0%,100%,.5);

Let’s also give the text a slight shad­ow, by using white we can give the illu­sion of let­ter­press.

text-shadow: 0 1px 1px hsla(0,0%,100%,.5);

Lastly, how about giv­ing the bubble some roun­ded corners, it is a bubble after all!

border-radius: 5px;

Step 4: Add an arrow

We are going to use a pseudo-ele­ment to add our arrow to the bot­tom right of our bubble. Internet Explorer 7 doesn’t sup­port pseudo-ele­ments but luck­ily it degrades grace­fully. Before we start styl­ing our arrow we are going to add the fol­low­ing line to our bubble class:

position: relative;

This allows us to use abso­lute pos­i­tion­ing to pos­i­tion the arrow rel­at­ive to the bubble. We will use the :after pseudo-ele­ment for our arrow. If you aren’t famil­i­ar with pseudo-ele­ments and would like to learn some more I would recom­mend read­ing this art­icle. We are also going to pro­duce a tri­angle using bor­ders, more inform­a­tion on that can be found here. Finally, we will use abso­lute pos­i­tion­ing to place the arrow appro­pri­ately.

Step 5: Give it a shadow

Giving the arrow the same shad­ow is not as easy though. Luckily we have a second pseudo-ele­ment to work with, let’s use that. Most of the rules we will be declar­ing for the arrow’s shad­ow will match that of the arrow itself so rather than rewrit­ing the rules let’s group the select­ors.