Drawing a triangle with CSS
Tags: css, html, webdev
Published: 2021-03-24 13:47:02

---
title: Drawing a triangle with CSS
published: true
description: Three different ways to draw a triangle in CSS.
tags: css,html,webdev
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oxl4s9sz91sng2urkrl9.png
canonical_url: https://alvaromontoro.com/blog/67970/drawing-a-triangle-with-css
---

In this post, we are going to see different methods to draw a triangle in CSS. We will focus on three in particular: the _traditional_ method using borders and two more modern options with `clip-path` and `linear-gradient()`.


## Using `border`

This is the "classic" way of drawing a triangle in CSS, and it seems like the most popular one by far. It consists of having a single colored border, leaving the others transparent. These are the steps to achieve it:

1. Set a `width` and `height` of 0.
2. Set the border color to transparent.
3. Set the top border to 0.
4. Set the side borders to half the width.
5. Set the bottom border to have the full height.
6. Set a color for the bottom border.

> Note: The steps above are for a specific triangle. The actual steps will change (slightly) depending on the type of triangle that we want to draw. In general, the idea is to set 2-3 borders as transparent and 1-2 borders with color and then adjust the border sizes.

It may not sound easy, but it is relatively simple:

<figure>
![Schema of how drawing a triangle with borders in CSS works](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/od6v6l2cmyl8wa4ef5ce.png)
<figcaption>Border sizes can be adjusted to point the triangle in any direction<br>&nbsp;</figcaption>
</figure>

Depending on where you want the triangle to point to, you will adjust the corresponding borders' sizes and colors.

{% codepen https://codepen.io/alvaromontoro/pen/VwPYNOo %}

This method appeared a long time ago, and it is a "hack." It **works in all browsers**, and it will continue working in future browsers, but it is not how the borders were intended to be used.

Because of that, it doesn't play nice when we try to add content. It doesn't scale properly, so the container size needs to be known, and the values need to be specific for that triangle.

Pros of this method:

- Support: it works in every browser (even old versions of IE)
- Simple: it's easy to program, as shown in the example above.

Cons of this method:

- Difficult to maintain: changing size requires changing the code.
- Rigid design: if we add content, the result will likely not be the expected one.

Borders will work very well in a specific situation: empty triangles with a fixed size. Outside of that, problems arise. We must remember that this is a hacky solution from a time when there were no other options.

## Using `background-image`

We could use an inline SVG in CSS, which would work fine... but it would be _cheating_, as we would be using an image instead of CSS.

Instead, let's create the triangle using [`background-image`](https://developer.mozilla.org/en-US/docs/Web/CSS/background-image) but without an actual image. We can achieve that by adding two [linear gradients](https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient()). One for each side of the triangle.

The idea would be to do this:

1. Add a `linear-gradient` towards the bottom right corner (transparent to red with a hard change at 50%)
2. Add a `linear-gradient` towards the top right corner (red to transparent with a hard change at 50%)
3. Set the size of both `linear-gradient` to 50% width
4. Position one `linear-gradient` at the beginning and another at the end of the container.

This sounds more complicated than the borders! And not going to lie, it is. Here is a schema of how it looks:

<figure>
![Schema showing two linear gradients forming a triangle](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7eu4pk08ov7lotheixta.png)
<figcaption>This is one of many ways to achieve a triangle<br>&nbsp;</figcaption>
</figure>

The result is graphically similar to the triangle created with the borders:

{% codepen https://codepen.io/alvaromontoro/pen/PoWqqoz %}

But it has some key differences: mainly, this solution is responsive to changes in the container's size. There's no need to calculate anything or use CSS variables.

Also, as the container is still a rectangle, formatting, positioning, and styling the text within the triangular shape is more "natural."

Pros of this method:

- Support: it works even in older browsers (IE10 and up.)
- Responsive: it adjusts to the container's size.
- Perfect for text: The container shape is not affected, so adding text or other content is straightforward.

Cons of this method:

- Complex: this option is probably the most complex one to develop.
- Tricky for options: having, for example, a linear gradient is more complicated (but feasible.)

## Using `clip-path`

[`clip-path`](https://developer.mozilla.org/en-US/docs/Web/CSS/clip-path) is the "latest" of the three. And I put "latest" between quotes because it has been supported for over 10 years in Firefox and Chrome (with prefix), and its support started around the same time as `linear-gradient()`.

With `clip-path`, you can define a clipping section which will be the only visible part of the element. To draw a triangle, we'd only have to define a polygon with three points like in the image:

<figure>
![Schema of how to create a triangle using clip-path](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p9yc8wcbey0wu4wlxbri.png)
<figcaption><code>polygon()</code> makes it easy and responsive<br>&nbsp;</figcaption>
</figure>

The code to achieve this is incredibly simple thanks to the `polygon()` function. We only need the bottom-left (0% 100%), center-top (50% 0%), and bottom-right (100% 100%) coordinates and we are done!

{% codepen https://codepen.io/alvaromontoro/pen/vYgOEeM %}

One important thing to remember is that everything outside the clipped area is basically _gone_. And that includes not only the content but also "external" elements like shadows, outlines, or borders. ([Adam Kuhn has a great solution for this](https://twitter.com/cobra_winfrey/status/1374360243363319812).)

Polygons are only the tip of the iceberg: circles, ellipses, and with the latest support for `path()`, basically, any shape that you can imagine is possible with `clip-path`.

Pros of this method:

- Easy: `clip-path` is a game-changer for CSS. It is powerful and versatile, allowing any shape and not only triangles.
- Responsive: it adjusts to the container's size and its changes.
- Customizable: gradients and effects are not a problem as long as they are __within the visible area__.

Cons of this method:

- Support: no version of IE supports `clip-path`. Not all functions are supported across the board (`polygon()` is, though).
- "Mistake prone": everything outside of the clipped area is gone, which may lead to unexpected results.

## Conclusion

CSS has improved over time and now provides drawing tools –such as `clip-path` or `background-image`– to create triangles (or shapes) that are simpler, more flexible, and easier to maintain than using borders.

It makes sense to move on from using the more rigid borders and start using the _appropriate_ tools for the task. The same way that we wouldn't hammer a nail to the wall using a screwdriver... we'd use a hammer!

Nevertheless, **each method has its pros and cons**, and there are situations in which one may be better than the others. If borders work for what you need, use them. But it would be natural for that method to fade away with time. 

We moved from table layouts to floating containers and then from floating containers to Flexbox and Grid. It would make sense to move from using borders to new methods more suited for the job.