Pure CSS Icons

This is something I was toying around with recently. It all started with some new button designs that leveraged a clever combination of pseudo-elements and the CSS border-triangle trick. I started thinking, "What else can we use this for?" The result is pretty cool, if not actually terribly useful (images are much more practical, and real HTML5 techniques are much less brittle on supported browsers), but I'd though I'd share this:

Below is an image of what these look like on supported browsers. Right now, I've only tested them on Firefox and Webkit.

To start these off, I decided to limit myself to a single element. I decided a <span> was appropriate, as it could contain explanatory text for accessibility:

The most interesting thing in the above code is the last style rule. The font-size sets the size of the icon. The transparent foreground color takes the span's text out of the picture. You'll notice that in all the future styling, I use only EMs for units. This allows us to alter the size of our icons globally by changing this font-size value. Alternately, we can add additional "small" and "large" classes to .icon which override the font-size.

I'm going to present these in order of descending complexity. I'll start off with the Document icon, since that's the hardest one, and illustrates most of the techniques I used. The Warning icon is a little easier, and once I've walked you through those two, there's no real need to explain the last three.

The individual icons are driven by classes. So first we add the "document" class to our icon markup:

To make the Document icon, we need two basic graphical elements, the page of the document, and some way to represent the folded-over corner. Happily, we know we can make triangles using element borders, and if we use the ::after pseudo-element, we can manipulate it independently of it's parent.

Unfortunately, the if we leave it at that, the "page" part of the icon will stick-out past the folded corner. We need a way to clip that corner off the original span. Since we can't clip on a diagonal, how do we do this?

The answer is to make use of the ::before pseudo-element to build up the page with the corner already missing:

On to the Warning icon. Again, we start by adding the "warning" class to our icon markup:

<span class="icon warning">Caution: </span>

To make the Warning icon, we need to make use of all three elements available to us. We want to preserve the actual span content for accessibility, so we need the ::after element to add "!". We could style the span element to form the triangular sign, but then we'd be left with pointy, sharp corners. Ideally, we want to round off the corners of the triangle. What I came up with was using the span element as a clipping boundary, the ::before element for the triangle, and the ::after element for the "!":