A simple LESS mixin for creating image-less arrow carets

As I’ve been writing BaseWeb and trying to move to a more image-less UI principle in my development projects, I’ve stumbled on a cool technique for creating triangle shapes in pure CSS. I’m not sure who came up with this but I originally found it in Twitter’s Bootstrap framework. Here’s how the CSS looks:

.triangle {
    display: inline-block;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0 45px 60px 45px;
    border-color: transparent transparent #000 transparent;
}

And you get a nicely drawn triangle, like this:

How it works

By defining border widths for three sides of a 0px by 0px element and setting the fourth side to 0, you create a triangle shape with the top angle pointing towards the side with the border width of 0. Another important part of this technique is to set the border colors to transparent except for the side opposite the 0 border width. Whatever color is defined on that side is what determines the color of the triangle.

In practice

Alright, so now we can draw triangles, but how can we put this new skill into practice? You can definitely be creative and come up with some great applications for this. But for our purposes, we’re going to use this as a way to create simple arrow/carets for our UIs.

So for our mixin, we want to be able to do a few things:

  • It needs to be modular: We want to be able to use this throughout our other stylesheets so it should be flexible and easy to apply to elements.
  • We need to be able to choose the direction: up, down, left and right. We could get more complicated and create up-right, right-down, down-left and left-up directions as well but the first four will do for what we need.
  • Options for setting the border width and color: Because you know, that would suck if we had to duplicate all this code for every variation we may need.

The mixin

#arrow {

    .base() {
        content: "\0020";
        display: block;
        width: 0;
        height: 0;
        border: 0 none;
        border-style: solid;
    }
    
    .up( @arrow-width, @arrow-color ) {
        .base();
        border-width: 0 @arrow-width @arrow-width @arrow-width;
        border-color: transparent;
        border-bottom-color: @arrow-color;
    }
    
    .right( @arrow-width, @arrow-color ) {
        .base();
        border-width: @arrow-width 0 @arrow-width @arrow-width;
        border-color: transparent;
        border-left-color: @arrow-color;
    }
    
    .down( @arrow-width, @arrow-color ) {
        .base();
        border-width: @arrow-width @arrow-width 0 @arrow-width;
        border-color: transparent;
        border-top-color: @arrow-color;
    }
    
    .left( @arrow-width, @arrow-color ) {
        .base();
        border-width: @arrow-width @arrow-width @arrow-width 0;
        border-color: transparent;
        border-right-color: @arrow-color;
    }
    
}

Now all we’re going to have to write to get an awesome caret is this:

#arrow > .right( 4px, #ccc );

The first parameter defines the border width and the second the color of the arrow caret.

Using the mixin

This is by no means an extensive list of all that’s possible, but here are a few examples of how we can put this mixin to work.