← Back to Home Page

Creating Triangles in Pure CSS

The original version of this article is archived if you would prefer that version.

This article features code examples in both Haml and HTML; Sass and CSS. If you are unfamiliar with Haml and Sass, please check out the Haml and Sass sites for more information and usage.

Note: All Haml examples in this article use the original, more Ruby-specific, attribute style versus the "HTML" style that is also available. All Sass is written in the original, non-SCSS, variant with prefixed colons on selectors. If you prefer to use a different Haml/Sass syntax, consult the above documentations on how to do so.

There's some interesting information online in regards to creating triangles and other polygonal shapes using only CSS. Tantek Çelik's article A Study of Regular Polygons and Scott Jehl's Image-free CSS Tooltip Pointers — A Use for Polygonal CSS? served as the jumping off point for this article.

I was curious to play with these concepts and see how they function cross-browser.

Creating a Simple Triangle with CSS

Here's the code for the above example:

// Haml

.triangle.basic

// Sass

.triangle :border-bottom 0 :height 0 :width 0 &.basic :border :left 25px solid transparent :right 25px solid transparent :top 40px solid red

// IE6-specific hacks

:_border-left-color black :_border-right-color black :_filter chroma(color=black)

/* HTML */

<div class="triangle basic"></div>

/* CSS */

.triangle { border-bottom: 0; height: 0; width: 0; } .triangle.basic { border-left: 25px solid transparent; border-right: 25px solid transparent; border-top: 40px solid red;

/* IE6-specific hacks */

_border-left-color: black; _border-right-color: black; _filter: chroma(color=black); }

To modify the look and size of the triangle, changing the left and right border sizes will yield triangles of different widths. Changing the size of border-top will affect the triangle's overall height.

Internet Explorer Bugs and Fixes

Note: In this example, IE6 is being specifically targeted using the underscore ("_") hack. Others, like * html, work just as well. You can also serve the IE6-specific styles in a seperate stylesheet via conditional comments.

Internet Explorer 6 does not comprehend setting a border colour to transparent. It seems to instead treat transparent as being equal to inherit, with the result being the left and right borders are set to the colour declared in the <body> tag of your CSS file.

Tervel Peykov has an article, Emulating border-color: transparent in Internet Explorer 6, which explains how IE6 can be "hacked" to display transparent borders using the propriatary Microsoft filter attribute. This is what you see being applied in the code under the section labled IE6-specific hacks.

As noted in Peykov's article, the thing to be careful of when applying the filter attritbute is to make sure to choose a colour that is not applied or nested anywhere else inside any parent elements in the document.

For example, if your default font colour is black then set the colour value in chroma() to something like pink or orange. If set to black, globally all black will become transparent!

Nested Triangles

To create the illusion of a triangle with a border, it is necessary to nest one triangle inside another:

Expanding on the code from the previous example:

// Haml

.triangle.basic.outer .triangle.basic.inner

// Sass

.triangle ... &.outer :position relative &.inner :position absolute &.basic :border :left 24px solid transparent :right 24px solid transparent :top 39px solid yellow :bottom 1px :left -24px

/* HTML */

<div class="triangle basic outer"> <div class="triangle basic inner"></div> </div>

/* CSS */

.triangle.outer { position: relative; } .triangle.inner { position: absolute; } .triangle.inner.basic { border-left: 24px solid transparent; border-right: 24px solid transparent; border-top: 39px solid yellow; bottom: 1px; left: -24px; }

Extending: Integration with Modal Boxes

Here's an example of how you can combine triangles with other elements to produce a simple modal box with a call-out.

View the page source to see how it's done.

Cross-browser Compatability

How do CSS triangles square up (HA!) in today's browsers? At the time of publication, by and large "okay." Outside of Firefox (3.6), most browsers — IE 6 to 8 included — tend to render the edges of the triangle very jagged or aliased looking. It's not perfect, but it's not totally awful either.

When it comes to overlaying or nesting multiple triangles, Internet Explorer 6 just falls flat. Applying the filter attribute to the inner triangle has the weird result of making the triangle below basically invisible.