DEV Community

Cover image for Drawing a triangle with CSS
Alvaro Montoro
Alvaro Montoro

Posted on • Originally published at alvaromontoro.com

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:

Schema of how drawing a triangle with borders in CSS works

Border sizes can be adjusted to point the triangle in any direction
 

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

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 but without an actual image. We can achieve that by adding two linear gradients. 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:

Schema showing two linear gradients forming a triangle

This is one of many ways to achieve a triangle
 

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

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 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:

Schema of how to create a triangle using clip-path

polygon() makes it easy and responsive
 

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!

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.)

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.

Top comments (12)

Collapse
 
robole profile image
Rob OLeary

Coincidence --> dev.to/dailydevtips1/css-shapes-tr...

Same topic, same day!

Collapse
 
alvaromontoro profile image
Alvaro Montoro

It can be. There has been some talk about triangles/shapes in CSS lately (at least 1 or 2 posts in the past week).

My post started with something I wrote on Twitter that got me roasted yesterday, mainly for making an absolute statement that people didn't agree with, so I wanted to add a longer explanation:

Collapse
 
robole profile image
Rob OLeary

😅 The perils of expressing yourself on Twitter!

Collapse
 
xr0master profile image
Sergey Khomushin

Thank you for the article!
Using CSS borders, you can create any triangles of different angles (but not more than 90). It is not at all necessary to divide by 2 and be limited to only this.
jsfiddle.net/m0zwLdju/

Collapse
 
alvaromontoro profile image
Alvaro Montoro

You are correct, that's not the only way to draw a triangle using the borders. I updated the article to add a note indicating that those are the steps for that specific triangle and other triangles will be slightly different:

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.

Collapse
 
robole profile image
Rob OLeary

Another con for clip-path is that you can't use box-shadow to create a shadow (you can use filter: drop-shadow() instead).

Outside of the realm of CSS art, I reach for SVG most of the time.

Collapse
 
alvaromontoro profile image
Alvaro Montoro

I agree, but one thing: clip-path will hide the shadow from a filter too.

Collapse
 
robole profile image
Rob OLeary

If you extend the clip-path beyond the base, you can include it.

Something like this gives you a 2px drop shadow..

 .triangle {
        background-color: red;
        width: 200px;
        height: 100px;
        margin: 0 auto;
        clip-path: polygon(50% 0%, 0% 200%, 100% 200%);
        filter: drop-shadow(0px 2px 0 black);
      }
Enter fullscreen mode Exit fullscreen mode

jsfiddle.net/robjoeol/68d350zr/9/

Collapse
 
afif profile image
Temani Afif

one line triangle using conic-gradient : jsfiddle.net/mwfskaLx/1/.. useful if we want to think angles instead of dimension
Also with mask jsfiddle.net/mwfskaLx/2/ and jsfiddle.net/mwfskaLx/3/

Collapse
 
alvaromontoro profile image
Alvaro Montoro

These are great options, and they would simplify considerably the background-image method. I had conic-gradient aside because Firefox didn't support it (not to mention IE). But that has changed now in FF, and this is a great use of it.

Collapse
 
calinzbaenen profile image
Calin Baenen

This is a very creative post. I like it.

Collapse
 
alvaromontoro profile image
Alvaro Montoro

Thanks!