Rounded Corners and CSS3

NOTE — June 7, 2010:
This page is a little out of date; the main Webkit browsers now work better with NO prefix on the styles. It’s time to say goodbye to -webkit-. In the following discussion, using the standard syntax will work with Chrome, Safari, and Opera as well. The table referenced below has been updated to reflect the newer browsers.

If you poke around this site you will see boxes with rounded corners. If you use Safari or Firefox, you will see even more.

Rounded corners are implemented here in two different ways. The main boxes with the drop shadows are done the old-fashioned way, the way that works on most browsers. Each corner is a graphic with an alpha-channel shadow, and the edges are yet more graphics, repeated as needed to span the distance between the corners. The boxes expand and contract infinitely in both directions. It’s not bad. It’s also a pain in the butt.

Yet, I like rounded corners. They seem friendlier. I have broken down, therefore, and in a few places I have added browser-specific style information to create a softer-feeling blog. Since the rounded corners are purely cosmetic — everything still works just fine in browsers that don’t support border-radius — I’m not too worried about it.

However, while I was looking into the border-radius CSS property, I discovered several sources that didn’t get it right.

Here’s the deal. The CSS3 standards draft includes a property called border-radius. Exactly how that property is going to work has not been finalized, but it’s not likely to undergo any more major revision. Meanwhile, Firefox and Safari have already worked out their own border-radius implementations, called -moz-border-radius and -webkit-border-radius respectively. Other browsers see the -moz and the -webkit prefixes and ignore the property.

Unfortunately, neither implementation matches how the proposed border-radius property will act. Oh, dear. When the browsers are updated to match the standard, those -vendor-border-radius properties may break. A lot of Web designers out there don’t seem to realize that.

NOTE: probably at this point you should open up this handy table to follow along.

It’s not all doom and gloom, however. As long as people using the vendor-specific border-radius properties keep things really simple, there won’t be a problem. Here’s the skinny:

All four corners with 15px radius
<style type="text/css"> .roundedBox { -webkit-border-radius: 15px; -moz-border-radius: 15px; border-radius: 15px; } </style>

will put a nice rounded corners on any block element of class roundedBox. Safari 4 and Firefox 3.5 (the browsers I have to test on) will work today, and when the formal border-radius is adopted and the other browsers support it, everyone will be happy. (Remember, of course, that in the meantime a large part of your audience will still see squared-off corners.)

The tricky part comes when one wants to specify elliptical corners, or specify different radii of curvature on different corners. When you start getting fancy, things get a little messed up. Let’s tackle the second one first, because it’s possible to find a way to specify the different corners that makes everyone happy. It’s just long-winded.

border-radius is really shorthand for four properties: border-top-left-radius, border-top-right-radius, and so forth. Therefore it’s perfectly safe to specify each corner independently, and all the browsers will act the same way:

top-left and bottom-right 20px radius, others 10px
<style type="text/css"> .roundedBox { -webkit-border-top-left-radius: 20px; -webkit-border-top-right-radius: 10px; -webkit-border-bottom-right-radius: 20px; -webkit-border-bottom-left-radius: 10px; /* different! */ -moz-border-radius-topleft: 20px; -moz-border-radius-topright: 10px; -moz-border-radius-bottomright: 20px; -moz-border-radius-bottomleft: 10px; border-top-left-radius: 20px; border-top-right-radius: 10px; border-bottom-right-radius: 20px; border-bottom-left-radius: 10px; } </style>

Note that the names of the four corner properties are different for Mozilla. Aargh. All the more reason to hope the spec is finalized soon. I put the four properties in the order the software considers them when parsing the shorthand notation, just to get into the habit.

All those lines of CSS can be a pain in the butt, but it’s bulletproof and will work on into the future. But wouldn’t it be nice if you could use shorthand for the border radius the same way you do for margins and padding? The boys at Mozilla thought so, and the CSS3 standards team thought so, too. Webkit (Safari) seems content to only support the long-winded method for now (at least support it properly – more on that later).

Before talking about the differences between the browsers and the CSS3 spec, let’s take a quick look at the theory. As with properties like border, the border-radius property is just a shorthand so you don’t have to specify each corner individually. If you use one number, like border-radius: 10px; the style will be applied to all the corners. If you supply four values, the four corners each get their radius set, starting with the upper left and working clockwise. So far, so good, but there’s trouble ahead.

[The following has been edited since it was first published. I first said that Mozilla was doing the following drawing wrong, but it looks like they have it right and Safari is wrong. Sorry for any confusion. To make up for it I added box-shadow here and there for browsers that support it. They’re sweet!]

The difference is elliptical corners. CSS3 calls for them, but the draft isn’t very well-written. The mystery lies in what should happen when two values are specified: border-radius: 20px 10px. When you are specifying a single corner, the result will be an elliptical curve. When using the shorthand, however, Safari draws all four corners with the same ellipse, but Firefox (and the CSS3 spec) draw round corners that turn out just like the example above.

According to the spec (by my reading), when using shorthand if you don’t use slashes you don’t get ellipses.

All four corners with elliptical curvature
<style type="text/css"> .roundedBox { /* four elliptical corners */ -webkit-border-radius: 20px 5px; moz-border-radius: 20px / 5px; border-radius: 20px / 5px; } </style>

NOTE: The most recent builds from match the spec. I don’t know when those changes will reach Safari, but sites using the two-value shorthand may have to deal with some inconsistencies between browser versions. Not sure, but I would avoid using that syntax just in case.

What about if four values are specified?

All corners different
<style type="text/css"> .roundedBox { /* four different circular corners */ /* no effect! */ -webkit-border-radius: 20px 10px 5px 30px; -moz-border-radius: 20px 10px 5px 30px; border-radius: 20px 10px 5px 30px; } </style>

Once again Webkit-based browsers like Safari and Chrome fall short. The Webkit team seems content to get the longhand method of specifying corners right, but not the shorthand. Mozilla, in the meantime, has worked out the most complex and versatile form of the shorthand, but disagrees with the spec fundamentals.

To use shorthand to specify four different elliptical corners, you would use something like:

-moz-border-radius: 20px 10px 20px 5px / 5px 10px;

where you specify up to four horizontal radii and then up to four vertical radii. The numbers before the slash are the horizontal radii, starting from the top left. If only two numbers are given, they alternate. Three numbers means top-right and bottom-left share. The y-radius values are the numbers after the slash, and are distributed the same way. Clear? Good.

I have read that if the text rendering is vertical, the horizontal and vertical parts are reversed, but I see nothing about that in the proposed specification.

This will make a lot more sense if you study the twoblue-shaded lines of the table.

While we’re looking at the table, note that Safari is perfectly capable of displaying the most complex borders, but they have not implemented the shorthand notation (except for the bit they did wrong). They’ve done the hard part, but left out the one-day coding job of parsing the shorthand strings into the properties for each corner. Odd. The rules are really very simple for a machine.

So what does this all mean?

In conclusion, while it’s possible to write different sets of -vendor-border-radius CSS properties and get what you want, things start to get quite messy. It’s a lot of effort for aesthetic touches that half your audience won’t see for the next couple of years. I’d advise just staying away from elliptical corners for now, and specifying round corners individually if any are different. It’s a bit more typing, but it’s a lot safer. Stay away from -webkit-border-radius: with two values.

3 thoughts on “Rounded Corners and CSS3

  1. Hey, good summary, thanks… just commenting to let you know that in a bunch of places you have “raduis” instead of “radius”… hopefully that didn’t affect your testing, but it might confuse future readers who land here, so you might want to do a quick search and replace. :)

Leave a Reply

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