How to Make a CSS Speech Bubble With a Drop Shadow

How to Make a CSS Speech Bubble With a Drop Shadow

Demo

This post will take 4 minutes to read.

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:

  1. Write the markup
  2. Basic styl­ing
  3. Improve the design of the bubble
  4. Add an arrow
  5. Give it a shad­ow

Want to see the fin­ished code? Click here.

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.

.bubble {
    background-color: #fff0a0;
    color: #333;
    display: inline-block;
    font: 16px/25px sans-serif;
    padding: 15px 25px;
}

I have also set the dis­play to inline-block so that the bubble doesn’t break if the win­dow is too nar­row.

Step 3: Improve the design of the bubble

Now that our bubble has some basic form we need to give it a design to make it stand out. Let’s give it a slight gradi­ent, we can do that with the fol­low­ing code:

background-image: -webkit-linear-gradient(top, hsla(0,0%,100%,.5), hsla(0,0%,100%,0));
background-image:    -moz-linear-gradient(top, hsla(0,0%,100%,.5), hsla(0,0%,100%,0));
background-image:     -ms-linear-gradient(top, hsla(0,0%,100%,.5), hsla(0,0%,100%,0));
background-image:      -o-linear-gradient(top, hsla(0,0%,100%,.5), hsla(0,0%,100%,0));
background-image:         linear-gradient(top, hsla(0,0%,100%,.5), hsla(0,0%,100%,0));

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.

.bubble:after {
    border-bottom: 25px solid transparent;
    border-right: 25px solid #fff0a0;
    bottom: -25px;
    content: '';
    position:
    absolute;
    right: 25px;
}

Step 5: Give it a shadow

Giving the bubble a drop shad­ow is quite easy, we simply add it to the box-shadow prop­erty that is already declared:

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

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.

.bubble:after,
.bubble:before {
    border-bottom: 25px solid transparent;
    border-right: 25px solid #fff0a0;
    bottom: -25px;
    content: '';
    position: absolute;
    right: 25px;
}

Now we simply rewrite the rules that will be dif­fer­ent. We will need to change the col­or to match that of the shad­ow, and also adjust the pos­i­tion­ing. This is the last bit of styl­ing we need:

.bubble:before {
    border-right: 25px solid hsla(0,0%,0%,.1);
    bottom: -28px;
    right: 22px;
}

Final Product:

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

.bubble {
    background-color: #fff0a0;
    background-image: -webkit-linear-gradient(top, hsla(0,0%,100%,.5), hsla(0,0%,100%,0));
    background-image:    -moz-linear-gradient(top, hsla(0,0%,100%,.5), hsla(0,0%,100%,0));
    background-image:     -ms-linear-gradient(top, hsla(0,0%,100%,.5), hsla(0,0%,100%,0));
    background-image:      -o-linear-gradient(top, hsla(0,0%,100%,.5), hsla(0,0%,100%,0));
    background-image:         linear-gradient(top, hsla(0,0%,100%,.5), hsla(0,0%,100%,0));
    border-radius: 5px;
    box-shadow: inset 0 1px 1px hsla(0,0%,100%,.5),
                3px 3px 0 hsla(0,0%,0%,.1);
    color: #333;
    display: inline-block;
    font: 16px/25px sans-serif;
    padding: 15px 25px;
    position: relative;
    text-shadow: 0 1px 1px hsla(0,0%,100%,.5);
}
.bubble:after,
.bubble:before {
    border-bottom: 25px solid transparent;
    border-right: 25px solid #fff0a0;
    bottom: -25px;
    content: '';
    position: absolute;
    right: 25px;
}
.bubble:before {
    border-right: 25px solid hsla(0,0%,0%,.1);
    bottom: -28px;
    right: 22px;
}

Now it’s time to exper­i­ment with what you have learnt!

Tweet this