Joel Glovier is a Visual Design Engineer at appendTo. He’s really passionate about intuitive user experiences, progressive enhancement, performance oriented CSS, and making things look beautiful. Joel’s post is about creating pure CSS triangles, a task that he finds himself doing a lot in his work at appendTo.
Over the past couple years plenty of great articles around the web have extolled the virtues of using pure CSS shapes for everything from subtle decorative elements, to complex interface icons. The primary benefits touted for constructing such visual elements with CSS alone include:
- That they can be easily edited within the stylesheet on the fly, or programmatically (as opposed to image files which typically must be edited in an image editor locally and then re-uploaded to the server);
- As part of a document’s stylesheet they do not require an extra http request to load (as opposed to image files which must be linked to from the stylesheet);
- Being pure CSS, they are rendered by the browser natively, and are device resolution independent (as opposed to bitmap based image files which have a defined resolution).
Generally speaking, the formula for using CSS shapes in a design is: 1) an html element + 2) positioning + 3) pseudo elements (optional) = a CSS Shape.
Many web designers and developers have embraced using CSS shapes in their projects. But rather than really understanding the magic behind the method, a lot of us just end up Googling for a suitable example, and then doing the old “copy/paste/tweak code dance” without really understanding what’s going on.
With that in mind, I want to specifically explain how CSS shapes work, starting with a fundamental shape: the triangle.
My Div — It Has Three Corners
So it’s easy to imagine how you get a pure CSS square or rectangle out of any html element: just set a height, width and background-color, and due to the nature of the box model, any block level element can appear to be a square or rectangle.
Same thing goes for rounded shapes like circles or ovals: just define height, width, background-color, and apply a border-radius greater than the element’s height and width, and you’ve got a rounded shape.
But because of how the box-model works and the fact that an HTML element cannot technically have only three sides, we need to create the appearance of three sides with a clever hack.
Now You See It, Now You Don’t
Because an element’s border-width, border-style, and border-color can be set either in shorthand for the entire element or individually on a side-by-side basis, we are going to use a little hack with border-color to fake the appearance of a three sided triangle.
The trick is using a combination of a values for border-color that includes a color value and the transparent value, revealing only only one or two borders. When we combine this with a 0 value height and width on the element, we can skew the visible borders into appearing like a triangular shape.
Breaking It Down
Let’s take a look at some exaggerated illustrations that will help illustrate how the hack works.

|
1 2 3 4 5 6 7 8 9 |
div { width: 220px; height: 220px; padding: 16px; border: 12px solid transparent; border-top-color: orange; border-right-color: purple; border-bottom-color: blue; border-left-color: yellow; } |

|
1 2 3 4 5 6 7 8 |
div { width: 0; height: 0; border: 116px solid transparent; border-top-color: orange; border-right-color: purple; border-bottom-color: blue; border-left-color: yellow; } |
height and width of 0, removed the padding, and increased the size of the borders to compensate for the missing area. Even in this crude illustration you can begin to see where triangles are beginning to take shape from our different colored borders.
|
1 2 3 4 5 |
div { width: 0; height: 0; border: 116px solid transparent; border-bottom-color: blue; } |
border-color value of transparent comes in. If we set border-color to transparent on all but one side, we are left with a single visible triangle shape. (Again, note that the dashed lines in my example image are for illustration purposes only, and would not actually be rendered with our code.)
|
1 2 3 4 5 6 |
div { width: 0; height: 0; border-bottom: 116px solid blue; border-left: 116px solid transparent; border-right: 116px solid transparent; } |
border-top-width entirely from our declaration, effectively reducing the size of our element to just the visible area. Because our visible triangle is only generated by the border-bottom, we no longer need the border-top at all. However, we do still need the border-left and border-right properties set to transparent, as that’s what gives the border-bottom any width at all. Without them border bottom would not be visible.
|
1 2 3 4 5 6 |
div { width: 0; height: 0; border-bottom: 116px solid blue; border-left: 58px solid transparent; border-right: 58px solid transparent; } |
border-left and border-right to illustrate how the proportions of the triangle can be skewed. In this example, I’ve reduced the side values in half, while keeping the bottom the same, but you could also reduce the bottom value instead, giving you a shorter triangle. Similarly, other combinations of values will produce different types of triangles.By Your Powers Combined
So why is it so important to understand how these shapes work, anyway? Is there something wrong with just Googling for an example and copy/paste dancing your way to the solution?
No, there isn’t per se. But one of the least touted benefits of using CSS Shapes – yet most powerful in my opinion – is the workflow efficiency factor. The fact that you don’t have to interrupt your workflow in the code editor to jump into an image editor and export an asset is just as important for developers as the actual site performance benefits of using pure CSS shapes.
But if you are just replacing jumping into an image editor with jumping into the browser to Google a solution, you’re still not getting as much benefit as there is to be had when you fully understand how creating the shape works, and can do it on the fly. Authoring efficiency for the win.




