A couple weeks ago I did a quick write-up for a concept of a speech bubble done with HTML and CSS. Here I thought I would do a quick pass at the structure of a comic panel. (Why yes I do enjoy comics, how can you tell?)
Let's start with the markup. We've got a div with the class "panel" and an image inside it. You could include speech bubbles in markup as another layer in the composition, or you could just include it in the image (assuming there's an accessible alternative, anyway).
The most important thing in the demo is the pile of linear gradients as a background. There are four of them, one for each side of the border. I originally went with a basic border, but it felt a little stiff and constructed, compared to the drawn look I was hoping for. Making the border out of gradients softened the border lines and helped take the focus away from the hard borders and toward the softer image inside. (Although, if the image were made of sharp edges, like a vector cartoon, the plain hard-edged borders would probably look better.)
For convenience's sake, I made the actual gradient into a custom property for easier editing, along with the border color and a control for the thickness. Assuming a plain black border, the gradient goes from black to transparent, making the insides of the border softer. The length of the gradient depends on the
borderWidth custom property.
I ended up softening the other side of the border using a box shadow, also controlled by
border-width. My initial attempts to do the whole thing with gradients was turned off by the fact that the border corners no longer met in the corner, but made an intersecting pattern and somewhat ruined the effect.
Finally, the choice to make the border on a
::after pseudo-element. This ensured that the border would stay on top of any elements put inside the panel. Also, because the border is its own element, I have the ability to experiment with blend modes, filters, different positions and sizes, and all sorts of compositing fun.
An extra benefit of putting the custom properties on the panel div that I'm only just now realizing, is that you can use those same values not just for the borders, but for other elements, like speech bubbles, that you put into the panel as well. If this ever makes its way into some CMS, that would be a great way to store display options. You could define all the option defaults for the whole page, override them on a per-panel basis, and again on a per-element basis.