DEV Community

Tero Auralinna
Tero Auralinna

Posted on • Originally published at auralinna.blog on

How to make a CSS speech bubble with borders and drop shadow

Here is an example how to create a CSS speech bubble with borders and drop shadow.

Simple speech bubble

Let's start by creating a simple one with just rounded corners and arrow.

Speech bubble

HTML code

We need just one div to create a simple speech bubble. Though <blockquote> is more semantic element in case you're using bubble for somebody's comment.

<div class="speech-bubble">
    <p><strong>Demo speech bubble</strong></p>
    <p>This is a simple CSS speech bubble.</p>
</div>

CSS

.speech-bubble {
    background: #efefef;
    -webkit-border-radius: 4px;
            border-radius: 4px;
    font-size: 1.2rem;
    line-height: 1.3;
    margin: 0 auto 40px;
    max-width: 400px;
    padding: 15px;
    position: relative;
}

.speech-bubble p {
    margin: 0 0 10px;
}
.speech-bubble p:last-of-type {
    margin-bottom: 0;
}

.speech-bubble::after {
    border-left: 20px solid transparent;
    border-top: 20px solid #efefef;
    bottom: -20px;
    content: "";
    position: absolute;
    right: 20px;
}

Borders and drop shadow

Now we have a base. Let's add borders and drop shadow next. We need to add new HTML element for the arrow because we need to simulate borders and drop shadow with another elements.

Speech bubble drop shadow

HTML code

Let's add HTML element <div class="speech-bubble-ds-arrow"></div> for arrow.

<div class="speech-bubble-ds">
    <p><strong>Demo speech bubble</strong></p>
    <p>This is CSS speech bubble with borders and drop shadow.</p>
    <div class="speech-bubble-ds-arrow"></div>
</div>

CSS

CSS is a little bit more complex here because we need to use ::before and ::after pseudo-elements. Class .speech-bubble-ds-arrow will be used for the shadow of the arrow and .speech-bubble-ds-arrow::before will be used for the border. Pseudo-element .speech-bubble-ds-arrow::after will be the arrow.

.speech-bubble-ds {
    background: #efefef;
    border: 1px solid #a7a7a7;
    -webkit-border-radius: 4px;
            border-radius: 4px;
    -webkit-box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.2);
            box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.2);
    font-size: 1.2rem;
    line-height: 1.3;
    margin: 0 auto 40px;
    max-width: 400px;
    padding: 15px;
    position: relative;
}

.speech-bubble-ds p {
    margin-bottom: 10px;
}
.speech-bubble-ds p:last-of-type {
    margin-bottom: 0;
}

.speech-bubble-ds-arrow {
    border-left: 21px solid transparent;
    border-top: 20px solid rgba(0, 0, 0, 0.2);
    bottom: -25px;
    position: absolute;
    right: 15px;
}
.speech-bubble-ds-arrow::before {
    border-left: 23px solid transparent;
    border-top: 23px solid #a7a7a7;
    bottom: 2px;
    content: "";
    position: absolute;
    right: 5px;
}
.speech-bubble-ds-arrow::after {
    border-left: 21px solid transparent;
    border-top: 21px solid #efefef;
    bottom: 4px;
    content: "";
    position: absolute;
    right: 6px;
}

Well, it's ready. You can modify arrow border values or absolute positioning to change arrow size or position.

Here is a code snippet at CodePen to play around with bubble styles.


This blog post was originally published on Auralinna.blog

Top comments (2)

Collapse
 
equinusocio profile image
Mattia Astorino • Edited

Hi, you can achieve the shadow with the same elements from the first example, just put this to the
speech-bubble:

.speech-bubble {
  filter: drop-shadow(6px 4px 0px rgba(0, 0, 0, 0.2));
  border: 1px solid black;
}

And this to the ::after:

.speech-bubble::after {
  bottom: -19px;
  filter: drop-shadow(1px 2px 0 black);
}
Collapse
 
teroauralinna profile image
Tero Auralinna

Hi, thanks for the tip! That also works well and simplifies code.