DEV Community

Cover image for CSS Comic Book Style Speech Bubble
codingdudecom
codingdudecom

Posted on • Originally published at coding-dude.com

CSS Comic Book Style Speech Bubble

Speech Bubble CSS

Creating speech bubbles with CSS is a simple job, but I made it simpler with this gist. Find the HTML & CSS code for it below.
For more explanations on how it works check out my extended CSS Speech Bubbles post on my CodingDude blog.

CSS Speech Bubbles

inspired by Comic Strip Template by PSDDude

Speech Bubble HTML Code:

<div class="speech-bubble">CSS IS AWESOME!!! 💥 DON'T YOU THINK?</div>
Enter fullscreen mode Exit fullscreen mode

Speech Bubble CSS Code:

.speech-bubble{
  --arrow-w:0.5em;
  --arrow-h:1em;
  --bubble-corners:0;
  --w:12em;
  --border-size:3px;
  --text-color:black;
  --bubble-color:white;
  --border-color:black;
}
.speech-bubble{
  text-align:center;
  font-family:cursive;
  font-size:20px;
  font-weight:bold;
  color:var(--text-color);
  background:var(--bubble-color);
  padding:1em;
  position:relative;
  border-radius:var(--bubble-corners);
  max-width:var(--w);
  box-shadow:0 0 0 var(--border-size) var(--border-color);
}

.speech-bubble.round{
  --bubble-corners:1em;
}

.speech-bubble.circle{
  --bubble-corners:100%;
  padding:2em;
}

.speech-bubble:before,.speech-bubble:after{
  content:"";
  position:absolute;
  bottom:calc(-1 * var(--arrow-h) * 2 + 0.5px);
  left:50%;
  border-style:solid;
  border-width:var(--arrow-h) var(--arrow-w);
  border-color:var(--bubble-color) transparent transparent;
}

.speech-bubble:before{
  border-width:calc(var(--arrow-h) + var(--border-size)) calc(var(--arrow-w) + var(--border-size));
  border-color:var(--border-color) transparent transparent;
  bottom:calc(-1 * var(--arrow-h) * 2 - 2.5*var(--border-size)); 
  left:calc(50% - var(--border-size));
}

.speech-bubble.t:after{
  border-color:transparent transparent var(--bubble-color);
  bottom:auto;
  top:calc(-1 * var(--arrow-h) * 2 + 0.5px);
}

.speech-bubble.t:before{
  border-width:calc(var(--arrow-h) + var(--border-size)) calc(var(--arrow-w) + var(--border-size));
  border-color:transparent transparent var(--border-color);
  bottom:auto;
  top:calc(-1 * var(--arrow-h) * 2 - 2.5*var(--border-size)); 
}

.speech-bubble.l:after{
  border-color:transparent var(--bubble-color) transparent transparent;
  bottom:auto;
  border-width:var(--arrow-w) var(--arrow-h);
  top:calc(50% - var(--arrow-w));
  left:calc(-1 * var(--arrow-h) * 2 + 0.5px);
}

.speech-bubble.l:before{
  border-width:calc(var(--arrow-w) + var(--border-size)) calc(var(--arrow-h) + var(--border-size));
  border-color:transparent var(--border-color) transparent transparent;
  bottom:auto;  
  top:calc(50% - var(--arrow-w) - var(--border-size));
  left:calc(-1 * var(--arrow-h) * 2 - 2.5*var(--border-size)); 
}

.speech-bubble.r:after{
  border-color:transparent transparent transparent var(--bubble-color);
  bottom:auto;
  left:auto;
  border-width:var(--arrow-w) var(--arrow-h);
  top:calc(50% - var(--arrow-w));
  right:calc(-1 * var(--arrow-h) * 2 + 0.5px);
}

.speech-bubble.r:before{
  border-width:calc(var(--arrow-w) + var(--border-size)) calc(var(--arrow-h) + var(--border-size));
  border-color:transparent transparent transparent var(--border-color);
  bottom:auto;
  left:auto;
  top:calc(50% - var(--arrow-w) - var(--border-size));
  right:calc(-1 * var(--arrow-h) * 2 - 2.5*var(--border-size)); 
}

.speech-bubble.pop{
  animation-name: pop;
  animation-duration: 0.5s;
  animation-timing-function:cubic-bezier(0.755, 0.050, 0.855, 0.060);
}

.speech-bubble.float{
  animation-name: float-up;
  animation-duration: 2s;
  animation-iteration-count: infinite;
  animation-timing-function:ease;
}

.speech-bubble.r.float{
  animation-name: float-left;
}

.speech-bubble.l.float{
  animation-name: float-right;
}

.speech-bubble.t.float{
  animation-name: float-down;
}

@keyframes pop {
  0% {transform: scale(0.8);}
  80% {transform: scale(1.1);}
  90% {transform: scale(0.9);}
  100% {transform: scale(1);}
}

@keyframes float-up {
  0% {transform: translateY(0);}
  50% {transform: translateY(calc(-1 * var(--arrow-h)));}
}

@keyframes float-left {
  0% {transform: translateX(0);}
  50% {transform: translateX(calc(-1 * var(--arrow-h)));}
}

@keyframes float-right {
  0% {transform: translateX(0);}
  50% {transform: translateX(var(--arrow-h));}
}

@keyframes float-down {
  0% {transform: translateY(0);}
  50% {transform: translateY(var(--arrow-h));}
}
Enter fullscreen mode Exit fullscreen mode

Speech Bubble CSS Classes & Customization

Customize the Speech Bubble Design with Provided CSS Classes
Use the following CSS classes together with the base .speech-bubble class:

  • t, l, r or b for placing the arrow top, left, right or bottom (by default the speech bubble arrow points downwards)
  • round or circle for bubble shape (by default the dialog box has square corners); TIP: Circle works best for dialog bubbles, because in old comic books and newspaper doodle drawings, that’s how they were drawn.
  • pop or float for animation (by default the text bubble is static)

Additional Customization via CSS Variables

  1. --arrow-w: This variable sets the width of the arrow of the speech bubble to 0.5em.
  2. --arrow-h: This variable sets the height of the arrow of the speech bubble to 1em.
  3. --bubble-corners: This variable determines the roundness of the bubble’s corners. A value of 0 indicates sharp corners (so a square text bubble) while something like 50% would make a circle or elliptical talking bubble.
  4. --w: This variable sets the maximum width of the speech bubble, which is 12em in this case.
  5. --border-size: It defines the size or thickness of the border around the speech bubble, which is set to 3px.
  6. --text-color: This variable sets the color of the text inside the speech bubble to black.
  7. --bubble-color: It determines the background color of the speech bubble itself, which is set to white.
  8. --border-color: This variable determines the color of the border around the speech bubble, also set to black.

Codepen Demo

You can follow me

My blog: coding-dude.com
Twitter: @codingdudecom

Top comments (0)