Triangles and speech bubbles

When I started using CSS3 I quickly realized how easy it was to make a circle.

div {
width: 30px;
height: 30px;
background-color: blue;
border-radius: 50%;
}

This made me think of new ways to incorporate html elements as design features instead of using images, which has the benefit of being faster to load. However, one basic shape seemed hard to achieve and that was the triangle. In truth, there is no way to make a triangle with only html and css. You can make a rectangle look like a triangle , but you have to cover up more than half of it with another object.

#div1 {
height: 10px;
width: 10px;
background-color: blue;
transform: translate(10px,5px) rotate(45deg);
z-index: 2;
position: relative;
}

#div2 {
height: 30px;
width: 30px;
background-color: lightgrey;
z-index: 3;
position: relative;
}

You can make pretty much any triangle this way, picking an appropriate rectangle to start from and then transform it and hide the part you don’t want.

div {
height: 15px;
width: 20px;
background-color: blue;
transform: translate(2px, 17px) skew(-10deg, 60deg);
}

You can make some decent speech bubbles this way.

Rawr!
div {
height: 15px;
width: 15px;
background-color: blue;
transform: translate(50px, 35px) skew(0deg, 60deg) rotate(-15deg);
}

Unfortunately skew() makes box-shadow go haywire (atleast in some browsers).

Rawr!

 

But you can get away with not having a shadow on the speech bubble arrow in most cases.

Rawr!

 

Another way to hide the unwanted part of the rectangle is to use overflow: hidden. This means we can make a pie chart.

a
 a
a
a
How it’s supposed to look: pie
#bounding-circle {
width: 50px;
height: 50px;
position: relative;
background-color: lightgrey;
border-radius: 50%;
overflow: hidden;
box-shadow: 1px 1px 3px rgba(0,0,0,0.5);
}

#blue {
width: 25px;
height: 25px;
background-color: blue;
transform: translate(25px, -23px) skew(0, -63deg);
}

#yellow {
width: 50px;
height: 50px;
background-color: yellow;
position: absolute;
bottom: 0; right: 0;
transform: translate(25px,69px) skew(0, 60deg);
}

#red {
width: 50px;
height: 50px;
background-color: red;
position: absolute;
right: 0; top: 0;
transform: translate(24px,0) rotate(45deg) skew(20deg, 20deg);
}

#green {
width: 25px;
height: 25px;
background-color: green;
position: absolute;
left: 0: bottom: 0;
}

I’ve omitted vendor-specific CSS for clarity in my examples.

Keep in mind that browsers that do not support CSS3 will have a not-so-graceful look. You can use position: absolute to position your triangle-element under the cover element to begin with to make the fallback more graceful. Since the z-index property requires positioned elements to work, this is probably the way to do it.

by Peter Lindsten.