We are currently working on a large site project that is going to have a chat tool with a web-based interface. We wanted to avoid the expected striped bars for each chat message and thought that iChat's speech bubbles provided a nice user experience. This style may also be used for comments on the site as well. It's important to note that it won't actually look like this, but there will be stylised speech bubbles that fit in with the site's design and they will fundamentally flow as outlined here.

The image above shows an iChat conversation between two individuals, and there a couple of things we liked about it:
The body of this article looks at taking a simple stream of div's and using just CSS 3 to make them look like iChat. Full source for the demo is attached in a handy zip at the bottom of the article, if you are curious about what it looks like you can interactively explore the different styles in a demonstration.
We need some test data, this is actually lifted from a chat we had to test, the only difference is we've modified the CSS class names from theySaid and youSaid to bubbleLeft and bubbleRight to make sense for this example.
Here's the HTML for the chat.
This gives us the rather unattractive chat below.

You can check this out the demo by clicking on 'No Style' (the default). Perhaps now is a good time to example the demo, and thank a couple of sites that contributed to it (unknowingly). Firstly there's a tool bar across the top with a set of buttons in it that when clicked on will go through the styles in this section. Two bits of liberated work here. The button style is taken and refined from http://www.zurb.com/playground/google-buttons, and excellent example of simple clean buttons. Finally, when these buttons are clicked on it switches the applicable style sheet for the page using a technique outlined by 37signals for switching style sheets in JavaScript. Thanks to both for making their work available.
The first thing we always focus on is the layout. The pretty can come later. To that end we created a simple style sheet that introduces the first styling for our bubbledLeft and bubbledRight CSS classes.
Although very simple, these classes introduce the left/right flow using float. There are other ways we could have done this (especially given the clear=both used) but we wanted to try something at the end to reduce consumed vertical space, and that needs floats. We also added a basic border (and little bit of padding) to make the messages stand-out and to give us something to build from. Here's how it looks.

Although in the rest of the steps I have not spent any time worrying about browsers that don't support the required CSS (luckily the latest versions of Safari, Chrome, FireFox and Opera do, with a small issue on the last step for FireFox 3.6 that could easily be solved with judicious use of CE Image in the template to resize the avatar image). However, we will obviously use Modernizr to pick up and respond to these issues. Whilst we could go to some efforts to make it look the same across all browsers we as a company have decided that unless specifically instructed by the client, we will degrade gracefully rather than try and look exactly the same on each browser. Our clients have been very comfortable with that, and with each site launched that has no user complaints from IE 7 users... we become more confident that this is the right approach. In fact, for sites with a strong social element we've seen the "peer pressure" to get the site in all its glory driving people to move to the latest version of their browser. This is a good thing.
Style 2 is a nod in the direction of compliant browsers, introduces an alternative colour for the left and right hand sides, and if border-radius is available (with vendor tags) uses those to suggest a direction of the speech bubble. In fact, if I were doing a very minimalist site, I'd be tempted to iterate this design a little. It's very clean.

OK, let's do something more interesting...
The CSS border-image property is very interesting, and perhaps a little misleading in it's title. It doesn't just apply to the border, but the background of the element as well. Other sites go into detail on the topic (such as CSS Tricks), but essentially you take an image such as the ones below...
...and determine the size of the corners in order to repeat the sections in between...
There are other options which you can read about, but we are interested in just one of the modes that will stretch the sections across the top, bottom, left and right along their borders, and fill the center with a stretch image of the middle chunk. We created two images for this purpose, baking in the different colours. Oh how I'd love to be able to apply shaders or rgb transforms in CSS. One thing that's often not made clear is that in order for border-image to work consistently you have to specify the border widths for the various sides. At least in Safari there are was some very unusual behaviour if you don't (including not always drawing the border as specified by the border-image property). The additional style for the left bubble is given below
If we apply this to our chat, we get the result shown below. But can you spot the issue? Our little arrow sticking out means that the top border is a little bigger than the bottom one. And as we've had to set the border width, we can see that the text is a little offset. Now, we could just pad out the bottom a little more, or adjust the image to have a few extra pixels. However, that doesn't feel right, in the next step we'll use another bit of CSS (CSS 2 this time) to get around the problem.

Firstly, we are going to upgrade our images a little and make something a little closer to our iChat goal for this exercise. This demands an even bigger offset as described above which is why the extra padding is not desirable, you end up with the border dictating the appearance, and it really shouldn't be that way around. Here are our images...
One of our big 'I get it' experiences came the first time we read this article by Nicolas Gallagher. The article not only highlights that the pseudo-elements :before and :after have been around for a while, but also has a great graphic showing how they are bounded by their parent element as a container. One of the concerns you see around these elements is that CSS should just be about styling, not content. We agree, and think that is exactly what they are about! We are going to use them to style the background for our bubbledLeft and bubbledRight cells. It's worth repeating the .bubbledLeft class as we are actually taking our old border-image out of it, and replacing it with some padding that will simply position our text perfectly within the bubble. In other words, because or bubble is now just part of the background to the element, we can just precisely position the content. Also note the addition of the position relative, it's going to create a co-ordinate system for our :before element. Remember Nicolas' article, the :before element is contained in the parent element. In the actual style sheet we just add this to both classes, but it's split out here for clarity.
OK, so now we have no border again, but we can use the :after element to give us that. We push it to the back with the z-index property then specify absolute positioning (and this will be even more important in the next stage) to fill the background to the message. Then tweaked border-image properties to work with the new images, and we should be good to go.
This gives us the not entirely unpleasant looking chat below! We are certainly getting somewhere.

However, we are still missing our avatars. If only there was some way to include those...
We could have done this a number of ways, but we wanted to show off some of the power of the pseudo-elements and the new background-image and size properties. This time we are going to use :after to add the avatars, and the background images, sized to 32x32 to draw the avatars at the bottom of the page. A little judicious application of border radius rounds them off nicely. However, we need to make some space for them so we add a margin to the main element.
Now we use the :after element to add in the avatar.
As you can see, this gives a great iChat like look. Even better we can tweak and style each element of the style (the bubble, the layout and position of the text within it, and the avatar) independently of each other. Used like this :before and :after are really all about pure styling. Note that we can now leverage the positioning to push the avatar image into the margin and position the image at the bottom of the chat message.

Now, remember we used floated the chats earlier, then just used clear: both? Well... there is just one more thing...
We'd like to stress this isn't something we've tested with users, but we think it's interesting enough to experiment with. What if... the left chat only clears left, and the right chat only clears right. That means messages on the left and right could overlap at times, without loosing the over all flow. At least, that's the theory. Why risk confusing users? Well, the chat, or indeed comments, may be being viewed on a mobile device where space is at a premium. We wanted to see if we could get more in without loosing the flow. So far feedback has been good, with beta-testers not even noticing. However, time will tell! It saves around 25% of the vertical space for this short conversation, so not really to be sniffed at, and certainly worth a look.

One of the things we've learned is just how rich CSS decoration of the cleanest content can be. This deployment is an expression engine one, and even our experiments with comments have shown easily templates can be made to leverage what is really some quite simple CSS. Although we are sure you could abuse :before and :after it's actually very hard to do so, and anything you put in the content property ends up being just decoration. We did consider some of the pure CSS speech bubble solutions out there (Nicolas again coming up with the goods Pure CSS speech bubbles, but rendering of tested slower on net-books and the constraints it placed on the design of the bubble a little restrictive. However, we are sure it could be done, and well understand the arguments for doing so. However, with the two chat bubble images being just 4kb we think images and image-border gives us a lot of design flexibility for a low bandwidth cost.
Now all that remains is for us to give the link to the demo one more time, and a download link for a zip of all the files you need to play with this yourself.
Tweet us up with any questions or insults @rougeExciter
| << Well that’s a relief, iExpression builds again! | Minor bug-fix update to iExpression for #eecms uploaded to App Store >> |