A Better Technique To Create A Speech Balloon With Pure CSS

In one of my older posts, we learned about creating a speech balloon with pure CSS. As I mentioned at the end of the post, the technique had a little flaw in it: in order to create an arrow along the box, we had to prepend a new div within the box div. Although it did serve the purpose, it didn’t look much sophisticated. In this post, I will try to explain how we can create the arrow without prepending a new div within the box div. Hence the only thing you will need to balloonify any HTML element would be to add class “balloon” in it.

CSS content Property

There is a less known property content in CSS2 which can be used to generate HTML content on the page. The generated HTML content isn’t available in DOM so you can’t examine it using FireBug. It looks a little odd to generate HTML content using CSS, because the purpose of CSS is to stylize the content and not to generate it. Nevertheless generating content using CSS does make life easier at a lot of instances, such as ours.

CSS :before and :after Pseudo Selectors

The content property can only be used with :before and :after pseudo selectors. If it is used with :before, the generated content is prepended to the target element. Likewise it is used with :after, the generated content is appended to the target element.

Using content Property To Create Balloon Arrow

It is now trivial to create the arrow with CSS now, all we have to do is to replace the selector .baloon .arrow with .baloon:before and add a new property content: ” in it.


    .baloon {
        background: #ccc;

        border-radius: 4px;
        -moz-border-radius: 4px;
        -webkit-border-radius: 4px;

        padding: 20px;
        position: relative;
        font-size: 12px;
        width: 300px;
        text-align: justify;
        color: #3a3a3a;

    .baloon:before {
        content: '';
        width: 0;
        height: 0;
        display: block;

        border-width: 10px;
        border-color: transparent #ccc transparent transparent;
        border-style: solid;

        position: absolute;
        top: 20px;
        left: -20px;


Now it is time to remove non-data markup from our HTML.

<div class="balloon">But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?</div>

Published by

Umar Ashfaq

Umar Ashfaq is a full-stack web developer. His core strength is building neat UIs with JavaScript on web but he also enjoys server side Java, NodeJS and Objective C. Follow him on twitter @umarashfaq87

Leave a Reply

Your email address will not be published. Required fields are marked *