CSS3 Gradient: Stop Sign

It’s the year 2011. CSS3 Gradients are kicking ass and making things more fun for web designers and developers. I personally haven’t tried them on real projects that I work on yet, but just looking at all the potential things they can do make me very excited.

Chris Coyier has written up a very nice and explanatory article about CSS Gradients at CSS-Tricks.com, it helps me learn about the basics of how gradients are done. Then today I’ve found Lea Verou’s “Beveled corners & negative border-radius with CSS3 gradients.” I’m very amazed by how intelligently she utilized CSS3 Gradients to make cut-off corners.

So I decided to have some fun with the code I took from Lea Verou’s post and try to make a Stop Sign with just HTML and CSS.

First I started out with a very simple HTML mock-up:


<div id="stopsign">
 <span class="stopword">STOP </span>
 </div>


Then here goes the CSS to make 4 gradients at all four of this stop sign’s corners:


#stopsign {
    background: #c00; /* fallback */
    background:
        -moz-linear-gradient(45deg,  transparent 40px, #c00 40px),
        -moz-linear-gradient(135deg, transparent 40px, #c00 40px),
        -moz-linear-gradient(225deg, transparent 40px, #c00 40px),
        -moz-linear-gradient(315deg, transparent 40px, #c00 40px);
    background:
        -o-linear-gradient(45deg,  transparent 40px, #c00 40px),
        -o-linear-gradient(135deg, transparent 40px, #c00 40px),
        -o-linear-gradient(225deg, transparent 40px, #c00 40px),
        -o-linear-gradient(315deg, transparent 40px, #c00 40px);
    background:
        -webkit-linear-gradient(45deg,  transparent 40px, #c00 40px),
        -webkit-linear-gradient(135deg, transparent 40px, #c00 40px),
        -webkit-linear-gradient(225deg, transparent 40px, #c00 40px),
        -webkit-linear-gradient(315deg, transparent 40px, #c00 40px);

    background-position: bottom left, bottom right, top right, top left;
    -moz-background-size: 50% 50%;
    -webkit-background-size: 50% 50%;
    background-size: 50% 50%;
    background-repeat: no-repeat;
}


Now it’s not done yet, I need to calculate the right width and height for my #stopsign div to make it look like an octagon as much as possible. Based on what I understand from Lea Verou’s article, the distance from the edge of the shape to where the corner is cut off is actually the length of the hypotenuse of an isosceles right-angled triangle. So in my case, since I use 40px as the length along the axis to the stop points in my gradients, that is, the legs of the isosceles right-angled triangle are 40 and 40. After calculation, the hypotenuse is roughly 57, then I multiple this number by 2, I get 114 for the combined length of two corners. A side of my octagon shape equals to double the length of one leg of that triangle, so I have 114+40*2 = 194, which will get me the width and height of the octagon.

The concluded formula is the following (Let W be the width of the Octagon and L be the length to the gradient stop position):
W = (sqrt(L^2 + L^2) + L) x 2

Note: The resulted number can be in decimal, like in this case it was 193.137. But if I round it up to 193, it will be smaller than the actual number I need, and it looks funky on Chrome, so I might as well just round it up to 194.

The height will be the same as the width.

So now I will add:


#stopsign {   
	height: 194px;
	width: 194px;
}


The result should look something like this:

css3-stopsign

DEMO

Note: This experiment should work in browsers that support the latest CSS3 gradient syntax. It works so far on my FireFox 3.6 and Chrome 11. It doesn’t work on Safari 5.0, but it should work on Safari 5.1 and Webkit Nightly.

This post has been updated/edited since its initial publication to fix language errors and added with extra notes about the experiment. Last updated: April 12, 2011.