Skip to main content
Photography of Alvaro Montoro being a doofus
Alvaro Montoro

Terrible Singer

Drawing Triangles with CSS Using Borders... an Exception

A long time ago, I wrote an article about triangles in CSS, and explained why the common border-based approach was far from ideal and should generally be avoided... Until now.

css html webdev showdev

If you search online for how to draw a triangular shape in CSS, chances are the top results will still recommend the border method, as described in this 15-plus-year-old CSS-Tricks article:

The idea is a box with zero width and height. The actual width and height of the arrow is determined by the width of the border. In an up arrow, for example, the bottom border is colored while the left and right are transparent, which forms the triangle.
.arrow-up {
  width: 0; 
  height: 0; 
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid black;
}

I still stand by most of what I wrote in my original article: this method is a hacky solution from a time when there were no other CSS options. It works, but it isn't how borders were meant to be used.

So what made me "change my mind" and say that it might be okay to use this method after all?

The answer is: logical properties.

Logical properties define direction-relative equivalentes to classic physical properties. Instead of thinking in terms of left/right or top/bottom, we think in terms of inline/block and start/end.

This is especially useful when creating layouts that must support multiple writing modes and reading directions. Not every language follows the familiar left-to-right, top-to-bottom flow of English. For example, Arabic is written right-to-left, while Japanese can be written top-to-bottom and right-to-left. A property like margin-right may work perfectly for English, French, or Spanish, but once the site is translated into Arabic or Japanese, the layout may break or behave unexpectedly.

Logical properties to the rescue! Instead of using margin-right, we can use margin-inline-end, and the spacing will automatically adjust based on the writing direction. No more exceptions or extra code!

And if you think this isn't a real problem or you've never run into these issues... bless your soul. Consider yourself lucky... or unlucky, depending on how you feel about dealing with an annoying (yet interesting) challenge... but mostly annoying.

Returning to triangles and borders: using CSS logical properties is the exception.

Instead of writing:

.triangle {
  width: 0; 
  height: 0; 
  border-bottom: 10px solid transparent;
  border-top: 10px solid transparent;
  border-left: 20px solid black;
}

Consider doing this:

.triangle {
  width: 0; 
  height: 0; 
  border-block-start: 10px solid transparent;
  border-block-end: 10px solid transparent;
  border-inline-start: 20px solid black;
}

By using logical properties, the triangle will point to the right in English, to the left in Arabic, and downward in traditional Chinese or Japanese. In other words, the triangle will always follow the writing direction.

Let's check an example to understand why this matters. Imagine a breadcrumb component: you have a list of nested pages and want to place a small triangle between each item, like this:

Breadcrumbs with left-to-right direction text, and arrows pointing right

If we use that same component on an Arabic site, the triangles still point to the right, while the text flows to the left. This happens when the triangles are created using images, clip-path, or even borders defined with physical properties.

Breadcrumbs with right-to-left direction text, but arrows pointing right

Here's a CodePen demo showing the four triangle-drawing methods mentioned in this article. It lets you switch the text direction to right-to-left or top-to-bottom (or both). Notice how the only triangle that adapts naturally in all directions is the one created using borders with logical properties.

And that's the use case. The exception where using borders to draw triangles is actually the better option. But only when logical properties are involved.

I still don't like border triangles. But, in this one specific case, they become the best and easiest tool.

Article originally published on