Journal »

De-pixelating the CSS Triangle

Get rid of those nasty edges!

While resources like the CSS Triangle Generator are particularly useful in getting what you want without having to give much thought to the matter, what comes out in production doesn’t necessarily always go as planned. While the output from generators like these are usually pretty solid (and very helpful), the way each particular browser renders non-equilateral triangles can vary, more than likely due to the fact people often forget—the fact that CSS triangles are, in fact, a hack in and of themselves.

Those crisp smooth edges you’re used to seeing can become a pixelated mess quickly and the only way to tame the best is—you guessed it—a CSS hack to trick the browsers into behaving. There are many StackOverflow threads with various suggestions for trying to take care of these cases, and even I had to use a combination of these on this very site to get things going smoothly (just look up!)

So let’s review the hacks that claim to do it:

RGBA over transparent

This particular trick says that rgba(0,0,0,0) instead of transparent will fix the pixelated edges issue due to the alpha channel. (Also remember to set a fallback for our favorite browser, IE8, if you care.)

border-color: transparent transparent transparent #fff;
border-color: rgba(0,0,0,0) rgba(0,0,0,0) rgba(0,0,0,0) #fff;

Border inset

This fix says that if Firefox seems to be rendering a strange gray border on your triangle, you can utilize a different border style (or the aforementioned RGBA trick above) to knock this one out.

border-style: inset;

Transform rotation

Seemed to be hit-or-miss for myself, but claims that doing a CSS transform on the triangle or 360 degrees will cause the browser to antialias the triangle more than without it there.

-webkit-transform: rotate(.05deg); 
-moz-transform: scale(1.1); 
-o-transform: rotate(.05deg); 
transform: rotate(.05deg);

Border dotted

If there was one fix to correct/hack the rendering of the CSS triangle back into shape, I’d likely recommend trying this one (and already have myself!) This one seems to knock it out of the park, especially in addition to the earlier RGBA fix. Take a look:

border-left: 180px solid #fff;
border-right: 180px solid #fff;
border-top: 30px dotted rgba(0,0,0,0);
border-bottom: 30px dotted rgba(0,0,0,0);

Border double (IE9+)

Update (3/30/2015): Jonas Krutil reported in the comments below that dotted may not be working in IE9+. His suggestion is to use double instead of dotted, in the same manner as the ‘dotted’ example above.

border-left: 180px solid #fff;
border-right: 180px solid #fff;
border-top: 30px double rgba(0,0,0,0);
border-bottom: 30px double rgba(0,0,0,0);

Transform scale

Seems to be particular to Firefox alone, but this vender-prefixed scale transformation seems to do the trick similarly to the rotation transform mentioned above.

-moz-transform: scale(.9999);


Hopefully this thread can help a fellow developer keep their sanity, just as these ongoing threads and helpful users, the sources for this writeup, have helped me in the past:

6 comments on “De-pixelating the CSS Triangle

    vsync  says...

    your RGBA “trick” lacks a proper explanation. why `rgba(255,255,255,0)` and no `rgba(0,0,0,0)` ? that is also transparent and it’s less code.

      Brett Hoffman  says...

      It doesn’t really matter what you use since you won’t be able to see the color anyway, given that the alpha channel is ‘0’. Using rgba(0,0,0,0) will save you a few bytes, I suppose.

      I’ll update the answer to reflect this. Thanks for your input!

Leave a Reply

Your email address will not be published. Required fields are marked *