All you need is a <div />:
<div class="speech-bubble">This speech bubble is created entirely with CSS, without any images or additional markup.</div>
… And the following CSS:
.speech-bubble { width: 200px; padding: 10px; background: #404040; color: #fff; font: normal 12px "Segoe UI", Arial, Sans-serif; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px; } .speech-bubble:after { content: ""; border: solid 10px transparent; /* set all borders to 10 pixels width */ border-top-color: #404040; /* the callout */ border-bottom: 0; /* we do not need the bottom border in this case */ width: 0; height: 0; overflow: hidden; display: block; position: relative; bottom: -20px; /* border-width of the :after element + padding of the root element */ margin: auto; }
The CSS is pretty self-explanatory, so lets not go into details. In a few words – we use the :after pseudo element to generate a new block element inside the <div>…</div>, and leave the rest to the magic of the borders of the HTML elements. Probably the most important thing for this solution is the bottom position, which equals the border-width of the :after element plus the padding of the root element. Obviously, with some more tweaking you can position the callout anywhere we need relative to the root element according to the design requirements. The only caveat I’ve noticed is that you cannot adequately apply box-shadow to the generated element, because the shadow wraps around the transparent borders and the result it pretty ugly.
This is just a simple illustration of what can be done with the polygonal oddities of CSS, and in fact there are numerous similar solutions around.
Here is the demo, and here is the download file in case you need it. Find more experiments here.
© 2006 - 2025 Martin Ivanov