These days I’ve been using a lot the possibility to draw triangles and arrows with pure CSS elements. I use them for small user interface elements: breadcrumbs, previous pages and next pages buttons, arrows on custom tooltips.

Drawing triangles in CSS

With this possibility we can draw elements which can be dynamically styled. Styles like colors and sizes can be authored when writing the CSS stylesheets. No need to update a bitmap file when we decide to change a simple color. And since the arrows are vector based they can be scaled and are beautifully rendered on Retina and HiDPI devices.

Natively CSS can force browsers to draw triangles with the help of thick borders of different colors. This is what we can use to draw simple arrows in pure CSS without relying on images.

Here is a sample of the trick to draw triangles. The first shape is a squared box with manually set width and height. We can see the diagonal lines drawn by the browsers to join adjacent borders of different colors. The second one is a zero-width and zero-height box:

See the Pen CSS Borders Triangles by Frederic Perrin (@blustemy) on CodePen.

And here the third sample has only one solid colored border, the three others all have a border color set to transparent. We’ve drawn an arrow! Or at least a triangle.

Mixins in Sass

This is what I’m going to simplify and generalize with Sass mixins. Only one mixin definition and four conditions for up, right, bottom, left directions. The mixin takes four parameters:

  • $dir is the direction
  • $base-width is the base length of the triangle
  • $length is the length of the triangle from the base to the tip of the triangle
  • $color is the fill color of the triangle, no gradients but it can be a color with opacity like rgba(0, 0, 0, 0.5) for a half transparent black color. Or even rgba(black, 0.5) since we’re in Sass code.
@mixin arrow($dir, $base-width, $length, $color) {
    width: 0; height: 0;
    border: ($base-width / 2) solid transparent;

    @if $dir == top {
        border-top: none;
        border-bottom-width: $length;
        border-bottom-color: $color;
    } @else if $dir == right {
        border-right: none;
        border-left-width: $length;
        border-left-color: $color;
    } @else if $dir == bottom {
        border-top-width: $length;
        border-bottom: none;
        border-top-color: $color;
    } @else if $dir == left {
        border-right-width: $length;
        border-left: none;
        border-right-color: $color;
    }
}

Theses mixins will be generally used with position: absolute; elements on :before and :after pseudo elements.

Demo

To illustrate this article, an example displaying tooltips like elements with the help of the mixin.

See the Pen Drawing Pure CSS Arrows With Sass Mixins by Frederic Perrin (@blustemy) on CodePen.