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 techniques to improve upon the design and add a seamless drop shadow. It is possible that you are familiar with many or all of the techniques used, if that is the case I would love for you to share an example of when you have had to use some outside 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 styling
  3. Improve the design of the bubble
  4. Add an arrow
  5. Give it a shadow

Want to see the finished 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 styling out of the way. This will include choosing a background color for the bubble, giving it some font styling and also some padding. I like to order the properties alphabetically.

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

I have also set the display to inline-block so that the bubble doesn’t break if the window is too narrow.

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 gradient, we can do that with the following 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 carefully at the code above you will notice that only white is being used, with the transparency fading out from 0.5 to 0. This enables us to keep our code easy to edit; if you want to change the color of the bubble you only have to alter a single value. Now that our button has some depth lets add a 1px highlight 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 shadow, by using white we can give the illusion of letterpress.

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

Lastly, how about giving the bubble some rounded corners, it is a bubble after all!

border-radius: 5px;

Step 4: Add an arrow

We are going to use a pseudo-element to add our arrow to the bottom right of our bubble. Internet Explorer 7 doesn’t support pseudo-elements but luckily it degrades gracefully. Before we start styling our arrow we are going to add the following line to our bubble class:

position: relative;

This allows us to use absolute positioning to position the arrow relative to the bubble. We will use the :after pseudo-element for our arrow. If you aren’t familiar with pseudo-elements and would like to learn some more I would recommend reading this article. We are also going to produce a triangle using borders, more information on that can be found here. Finally, we will use absolute positioning to place the arrow appropriately.

.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 shadow is quite easy, we simply add it to the box-shadow property 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 shadow is not as easy though. Luckily we have a second pseudo-element to work with, let’s use that. Most of the rules we will be declaring for the arrow’s shadow will match that of the arrow itself so rather than rewriting the rules let’s group the selectors.

.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 different. We will need to change the color to match that of the shadow, and also adjust the positioning. This is the last bit of styling 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 experiment with what you have learnt!

Tweet this