Introducing border-radius

Designers have been including rounded corners in their designs for years. In the early 2000s, when webmasters were creating table based layout, they would include tiny little table cells to add in little corners. With the end of table based layouts, web masters created nifty little tricks. From sliding doors to adding corners with javascript, to the three slice technique, we tried and cried over it all since 2004. Our solutions have involved hours of slicing and dicing images, and millions of non-semantic html hooks for those image.

A little history

Requiring images for decorative corners is a maintenance nightmare. The extra http requests to serve the images slowed down the page load and added to site bandwidth. Rounded corners require either 4 separate images — one for each corner — or a larger sprite image that includes all 4 corners if the design allows, which requires the addition of three, and sometimes 4, hooks for those corners.
And for what? A little decoration.

No more! Enough with markup clutter, extra http requests for decorative images
and JavaScript for presentation. It’s time to let the browser do our heavy lifting, especially since this ‘heavy lifting’ is really very light weight.

The CSS3 border-radius property is not supported on over 60% of the browsers surfing the web. So, why aren’t you using them? The CSS3 border-radius property allows you to create native rounded corners using only CSS. No divitis. No classitis. No extra http requests. No wasted hours in Photoshop.

The border radius property first raised it’s beautiful little head in 2005. Webkit was the first to support the border-radius property, but seemingly is the last to fully support it (more about that later).

With the border-radius property, you can create rounded corners without images in all modern browsers and IE9. You can create rounded corners, elliptical corners, uneven corners and odd effects.

So, how do you create these rounded corners? The syntax is slightly different for rounded corners than for elliptical corners. You can created 4 identical rounded corners with a single value, declare up to four different values — one for each rounded corner, or declare uneven corners by separating the horizontal radius from the vertical radius declarations with a slash in the shorthand or space in the long hand.

Most designs call for rounded corners, so let’s start with round corners first:

The syntax (round corners):

You can use the shorthand to declare identical (declare one value) or up to four different sized corner radii. Or, you can use the long hand to declare each corner separately:

border-radius:  <all-four-same-sized-corners>;
border-radius:  <TL & BR> <TR & BL>;
border-radius:  <TL> <TR> <BR> <BL>;


border-top-right-radius: <TR>;
border-bottom-right-radius: <BR>;
border-bottom-left-radius: <BL>;
border-top-left-radius: <TL>;

The code:

Generally, you will want all four corners to have the same look and feel, so you will want all four corners to be equal EXCEPT in the case of top navigation bar tabs, where you will want the top corners to be round and the bottom corners to be rectangular.

You can use the shorthand:

.box {
    border-radius: 1em;
.tab {
    border-radius: 0.5em 0.5em 0 0;

or you can use the longhand:

.box {
    border-top-right-radius: 1em;
    border-bottom-right-radius: 1em;
    border-bottom-left-radius: 1em;
    border-top-left-radius: 1em;
.tab {
    border-top-right-radius: 0.5em;
    border-bottom-right-radius: 0.5em;

The above will create rounded corners: the vertical and horizontal sides of each corner will be the same: the horizontal radius is the same as the vertical radius. But what if you want elliptical corners? Rounded, but not actually round? Border radius allows for that.

The syntax (rounded or elliptical corners):

If you want rounded corners that are elliptical instead of round, there’s a syntax for that. In the shorthand syntax, separate the horizontal radius from the vertical radius declarations with a slash.

border-radius:  <vertical-radius values> / <horizontal-radius values>;
border-radius:  <TL & BR> <TR & BL> / <TL & BR> <TR & BL>;
border-radius:  <TL> <TR> <BR> <BL> / <TL> <TR> <BR> <BL> ;

If you are using the longhand properties, separate the two radii with a space instead. Notice the values above have a slash, the values below do not.

border-top-right-radius: <TR vertical> <TR horizontal>;
border-bottom-right-radius: <BR vertical> <BR horizontal>;
border-bottom-left-radius: <BL vertical> <BL horizontal>;
border-top-left-radius: <TL vertical> <TL horizontal>;

The code:

These two declarations are equivalent

.shorthand {
    border-radius: 2em 1em 4em 3em/ 0.5em 3em;
.longhand {	
    border-top-left-radius:     2em 0.5em;
    border-top-right-radius:    1em 3em;
    border-bottom-right-radius: 4em 0.5em;
    border-bottom-left-radius:  3em;

And now for the bad news

While border-radius property has widespread browser support, there are some discrepancies in browser support.

Older Internet Explorer versions

Border-radius is not supported in IE6, IE7 or IE8. Remember that users access your web site with only one browser. They don’t look at all the different browsers: only web developers do that. So, visitors using these browsers will not see your beautifully rounded corners, but they also won’t know that they are missing anything. Rounded corners are an enhancement. They’re generally not critical to the content of your site. There’s an HTC file called CSS Curved Corner by Remiz Rahnas that can create rounded corner effects for old versions of IE.

Older non-IE browsers that are still lingering

If you’re still supporting Firefox 3.6 and or Safari 4 you’ll want to add the -moz- and -webkit- vendor prefixes respectively. Since Safari 5 was released over a year ago, and Safari 4 has less than 0.75% market share, I have dropped the -webkit- prefix syntax. At the time of this writing, while Firefox 4 has surpassed Firefox 3.6 in the USA market, the trend is not worldwide, so I am still including -moz- prefixed corners. Also, older versions of Firefox used a non-standards syntax for the long hand, so when declaring -moz- prefixed border radii, use the shorthand. If you want to use the long hand, I recommend using the border radius generator to get the FF3.6 and Safari 4 and earlier long hand markup.

Quirks in Modern Browsers

Opera, IE9, Safari 5, Firefox 4 and Chrome all understand the vendorless recommended standard syntax for the four long hand properties and the single shorthand border-radius property, but some browsers do have some bugs:

Safari 5 does not understand percentage values for rounded corners. This is resolved in the webkit nightly builds, so will be resolved in Safari 6. In the meantime, since it doesn’t understand %, it will ignore the entire declaration. The hack is to declare the border radius in other length units first, then declare your percent version for all browsers that do understand percentage values.

Opera currently also have bugs with percentage values. It does understand percents, but does not render them correctly in some cases. The values in elliptical corners is slightly off, and has been fixed in the Opera Next build (build 1024), so will be fixed in their next launch most likely. In most cases, therefore, a hack may not be necessary. When an element is floated, the border radius is completely off in Opera. The border-radius is huge, making the element look almost rectangular, as if there were no border-radius set. If you’re ok with graceful degradation, the Opera user won’t be negatively impacted: they will just see almost what IE 7 users see. If you’re not OK with that, either don’t float your rounded elements if you’ve used percentage values as your radius length, or use other length types (em, px, etc) if your element is floated.

HSL: Hue Saturation and Lightness

CSS3 adds numerical hue-saturation-lightness (HSL) colors as a more intuitive complement to numerical RGB colors. RGB colors are hardware-oriented. They reflect the fact that CRT monitors displayed colors based on red, green and blue. However, RGB is not the way humans tend to see colors.
RGB is non-intuitive.

Designers generally define colors based on the hue, saturation and brightness or lightness of a color. HSL defines colors this way: H=hue, S=saturation, L=lightness.

The Hue is represented as an angle of the color circle (i.e. the rainbow represented in a circle), with the ‘degrees’ of the circle pointing to different hues. HSL hues are defined as integers representing the degrees or angles of this circle with red=0 (red=360 too), green=120, and blue=240. The saturation and lightness are represented as percentages. For saturation, 100% is full saturation, and 0% is a shade of gray. For lightness, 0% lightness is black, 100% lightness is white, and 50% lightness is “normal”.


hsl(hue[0-360], saturation[%], lightness[%]); 

When it comes to black, white and grey, since there is no saturation (or, in the case of white, full saturation), we could have used any value for the hue.

Named Color Hex RGB HSL
black #000000 rgb(0,0,0) hsl(0, 0%, 0%)
dimgray / dimgrey #696969 rgb(105,105,105) hsl(0, 0%, 41%)
gray / grey #808080 rgb(128,128,128) hsl(0, 0%, 50%)
darkgray / darkgrey #A9A9A9 rgb(169,169,169) hsl(0, 0%, 66%)
silver #C0C0C0 rgb(192,192,192) hsl(0, 0%, 75%)
lightgray / lightgrey #D3D3D3 rgb(211,211,211) hsl(0, 0%, 83%)
gainsboro #DCDCDC rgb(220,220,220) hsl(0, 0%, 86%)
whitesmoke #F5F5F5 rgb(245,245,245) hsl(0, 0%, 96%)
white #FFFFFF rgb(255,255,255) hsl(0, 100%, 100%)

Table 1: The HSL, RGB and Hex values of the named grey colors

The advantage of HSL over RGB is that it is far more intuitive: you can guess at the colors you want, and then tweak. It is also easier to create sets of matching colors (by keeping the hue the same and varying the lightness/darkness, and saturation).

Below are the rest of the named colors in order of hue.

Named Color Hex RGB HSL
maroon #800000 rgb(128,0,0) hsl(0, 100%, 25%)
darkred #8B0000 rgb(139,0,0) hsl(0, 100%, 27%)
red #FF0000 rgb(255,0,0) hsl(0, 100%, 50%)
snow #FFFAFA rgb(255,250,250) hsl(0, 100%, 99%)
rosybrown #BC8F8F rgb(188,143,143) hsl(0, 25%, 65%)
indianred #CD5C5C rgb(205,92,92) hsl(0, 53%, 58%)
brown #A52A2A rgb(165,42,42) hsl(0, 59%, 41%)
firebrick #B22222 rgb(178,34,34) hsl(0, 68%, 42%)
lightcoral #F08080 rgb(240,128,128) hsl(0, 79%, 72%)
mistyrose #FFE4E1 rgb(255,228,225) hsl(6, 100%, 94%)
salmon #FA8072 rgb(250,128,114) hsl(6, 93%, 71%)
tomato #FF6347 rgb(255,99,71) hsl(9, 100%, 64%)
darksalmon #E9967A rgb(233,150,122) hsl(15, 72%, 70%)
orangered #FF4500 rgb(255,69,0) hsl(16, 100%, 50%)
coral #FF7F50 rgb(255,127,80) hsl(16, 100%, 66%)
lightsalmon #FFA07A rgb(255,160,122) hsl(17, 100%, 74%)
sienna #A0522D rgb(160,82,45) hsl(19, 56%, 40%)
seashell #FFF5EE rgb(255,245,238) hsl(25, 100%, 97%)
chocolate #D2691E rgb(210,105,30) hsl(25, 75%, 47%)
saddlebrown #8B4513 rgb(139,69,19) hsl(25, 76%, 31%)
peachpuff #FFDAB9 rgb(255,218,185) hsl(28, 100%, 86%)
sandybrown #F4A460 rgb(244,164,96) hsl(28, 87%, 67%)
peru #CD853F rgb(205,133,63) hsl(30, 59%, 53%)
linen #FAF0E6 rgb(250,240,230) hsl(30, 67%, 94%)
darkorange #FF8C00 rgb(255,140,0) hsl(33, 100%, 50%)
bisque #FFE4C4 rgb(255,228,196) hsl(33, 100%, 88%)
tan #D2B48C rgb(210,180,140) hsl(34, 44%, 69%)
burlywood #DEB887 rgb(222,184,135) hsl(34, 57%, 70%)
antiquewhite #FAEBD7 rgb(250,235,215) hsl(34, 78%, 91%)
crimson #DC143C rgb(220,20,60) hsl(35, 83%, 58%)
navajowhite #FFDEAD rgb(255,222,173) hsl(36, 100%, 84%)
blanchedalmond #FFEBCD rgb(255,235,205) hsl(36, 100%, 90%)
papayawhip #FFEFD5 rgb(255,239,213) hsl(37, 100%, 92%)
moccasin #FFE4B5 rgb(255,228,181) hsl(38, 100%, 85%)
orange #FFA500 rgb(255,165,0) hsl(39, 100%, 50%
wheat #F5DEB3 rgb(245,222,179) hsl(39, 77%, 83%)
oldlace #FDF5E6 rgb(253,245,230) hsl(39, 85%, 95%)
floralwhite #FFFAF0 rgb(255,250,240) hsl(40, 100%, 97%)
goldenrod #DAA520 rgb(218,165,32) hsl(43, 74%, 49%)
darkgoldenrod #B8860B rgb(184,134,11) hsl(43, 89%, 38%)
cornsilk #FFF8DC rgb(255,248,220) hsl(48, 100%, 93%)
gold #FFD700 rgb(255,215,0) hsl(51, 100%, 50%)
lemonchiffon #FFFACD rgb(255,250,205) hsl(54, 100%, 90%)
khaki #F0E68C rgb(240,230,140) hsl(54, 77%, 75%)
palegoldenrod #EEE8AA rgb(238,232,170) hsl(55, 67%, 80%)
darkkhaki #BDB76B rgb(189,183,107) hsl(56, 38%, 58%)
olive #808000 rgb(128,128,0) hsl(60, 100%, 25%)
yellow #FFFF00 rgb(255,255,0) hsl(60, 100%, 50%)
lightyellow #FFFFE0 rgb(255,255,224) hsl(60, 100%, 94%)
ivory #FFFFF0 rgb(255,255,240) hsl(60, 100%, 97%)
beige #F5F5DC rgb(245,245,220) hsl(60, 56%, 91%)
lightgoldenrodyellow #FAFAD2 rgb(250,250,210) hsl(60, 80%, 90%)
olivedrab #6B8E23 rgb(107,142,35) hsl(80, 60%, 35%)
yellowgreen #9ACD32 rgb(154,205,50 hsl(80, 61%, 50%);
darkolivegreen #556B2F rgb(85,107,47) hsl(82, 39%, 30%)
greenyellow #ADFF2F rgb(173,255,47) hsl(84, 100%, 59%)
lawngreen #7CFC00 rgb(124,252,0) hsl(90, 100%, 49%)
chartreuse #7FFF00 rgb(127,255,0) hsl(90, 100%, 50%)
darkgreen #006400 rgb(0,100,0) hsl(120, 100%, 20%)
green #008000 rgb(0,128,0) hsl(120, 100%, 25%)
lime #00FF00 rgb(0,255,0) hsl(120, 100%, 50%)
honeydew #F0FFF0 rgb(240,255,240) hsl(120, 100%, 97%)
darkseagreen #8FBC8F rgb(143,188,143) hsl(120, 25%, 65%)
forestgreen #228B22 rgb(34,139,34) hsl(120, 61%, 34%)
limegreen #32CD32 rgb(50,205,50) hsl(120, 61%, 50%)
lightgreen #90EE90 rgb(144,238,144) hsl(120, 73%, 75%)
palegreen #98FB98 rgb(152,251,152) hsl(120, 93%, 79%)
seagreen #2E8B57 rgb(46,139,87) hsl(146, 50%, 36%)
mediumseagreen #3CB371 rgb(60,179,113) hsl(147, 50%, 47%)
springgreen #00FF7F rgb(0,255,127) hsl(150, 100%, 50%)
mintcream #F5FFFA rgb(245,255,250) hsl(150, 100%, 98%)
mediumspringgreen #00FA9A rgb(0,250,154) hsl(157, 100%, 49%)
aquamarine #7FFFD4 rgb(127,255,212) hsl(160, 100%, 75%)
mediumaquamarine #66CDAA rgb(102,205,170) hsl(160, 51%, 60%)
turquoise #40E0D0 rgb(64,224,208) hsl(174, 72%, 56%)
lightseagreen #20B2AA rgb(32,178,170) hsl(177, 70%, 41%)
mediumturquoise #48D1CC rgb(72,209,204) hsl(178, 60%, 55%)
teal #008080 rgb(0,128,128) hsl(180, 100%, 25%)
darkcyan #008B8B rgb(0,139,139) hsl(180, 100%, 27%)
aqua / cyan #00FFFF rgb(0,255,255) hsl(180, 100%, 50%)
cyan / aqua #00FFFF rgb(0,255,255) hsl(180, 100%, 50%)
lightcyan #E0FFFF rgb(224,255,255) hsl(180, 100%, 94%)
azure #F0FFFF rgb(240,255,255) hsl(180, 100%, 97%)
darkslategray / darkslategrey #2F4F4F rgb(47,79,79) hsl(180, 25%, 25%
paleturquoise #AFEEEE rgb(175,238,238) hsl(180, 65%, 81%)
darkturquoise #00CED1 rgb(0,206,209) hsl(181, 100%, 41%)
cadetblue #5F9EA0 rgb(95,158,160) hsl(182, 25%, 50%)
powderblue #B0E0E6 rgb(176,224,230) hsl(187, 52%, 80%)
deepskyblue #00BFFF rgb(0,191,255) hsl(195, 100%, 50%)
lightblue #ADD8E6 rgb(173,216,230) hsl(195, 53%, 79%)
skyblue #87CEEB rgb(135,206,235) hsl(197, 71%, 73%)
lightskyblue #87CEFA rgb(135,206,250) hsl(203, 92%, 75%)
steelblue #4682B4 rgb(70,130,180) hsl(207, 44%, 49%)
aliceblue #F0F8FF rgb(240,248,255) hsl(208, 100%, 97%)
dodgerblue #1E90FF rgb(30,144,255) hsl(210, 100%, 56%)
slategray / slategrey #708090 rgb(112,128,144) hsl(210, 13%, 50%)
lightslategray / lightslategrey #778899 rgb(119,136,153) hsl(210, 14%, 53%)
lightsteelblue #B0C4DE rgb(176,196,222) hsl(214, 41%, 78%)
cornflowerblue #6495ED rgb(100,149,237) hsl(219, 79%, 66%)
royalblue #4169E1 rgb(65,105,225) hsl(225, 73%, 57%)
navy #000080 rgb(0,0,128) hsl(240, 100%, 25%)
darkblue #00008B rgb(0,0,139) hsl(240, 100%, 27%);
mediumblue #0000CD rgb(0,0,205) hsl(240, 100%, 40%)
blue #0000FF rgb(0,0,255) hsl(240, 100%, 50%)
ghostwhite #F8F8FF rgb(248,248,255) hsl(240, 100%, 99%)
midnightblue #191970 rgb(25,25,112) hsl(240, 64%, 27%)
lavender #E6E6FA rgb(230,230,250) hsl(240, 67%, 94%)
darkslateblue #483D8B rgb(72,61,139) hsl(248, 39%, 39%)
slateblue #6A5ACD rgb(106,90,205) hsl(248, 53%, 58%)
mediumslateblue #7B68EE rgb(123,104,238) hsl(249, 80%, 67%)
mediumpurple #9370DB rgb(147,112,219) hsl(260, 60%, 65%)
blueviolet #8A2BE2 rgb(138,43,226) hsl(271, 76%, 53%)
indigo #4B0082 rgb(75,0,130) hsl(275, 100%, 25%)
darkorchid #9932CC rgb(153,50,204) hsl(280, 61%, 50%)
darkviolet #9400D3 rgb(148,0,211) hsl(282, 100%, 41%)
mediumorchid #BA55D3 rgb(186,85,211) hsl(288, 59%, 58%)
purple #800080 rgb(128,0,128) hsl(300, 100%, 25%)
darkmagenta #8B008B rgb(139,0,139) hsl(300, 100%, 27%)
fuchsia / magenta #FF00FF rgb(255,0,255) hsl(300, 100%, 50%)
thistle #D8BFD8 rgb(216,191,216) hsl(300, 24%, 80%)
plum #DDA0DD rgb(221,160,221) hsl(300, 47%, 75%)
violet #EE82EE rgb(238,130,238) hsl(300, 76%, 72%)
orchid #DA70D6 rgb(218,112,214) hsl(302, 59%, 65%)
mediumvioletred #C71585 rgb(199,21,133) hsl(322, 81%, 43%)
deeppink #FF1493 rgb(255,20,147) hsl(328, 100%, 54%)
hotpink #FF69B4 rgb(255,105,180) hsl(330, 100%, 71%)
lavenderblush #FFF0F5 rgb(255,240,245) hsl(340, 100%, 97%)
palevioletred #DB7093 rgb(219,112,147) hsl(340, 60%, 65%)
pink #FFC0CB rgb(255,192,203) hsl(350, 100%, 88%)
lightpink #FFB6C1 rgb(255,182,193) hsl(351, 100%, 86%)

Table 2: The HSL, RGB and Hex values of named colors sorted by hue

You’ll note that the colors in the table above go from red to orange to yellow to green to blue to purple and pink and back to red. As noted before, red=0 and red=360, with all the other hues coming in between.

While named colors are limited, HSL color combinations are limitless. Try picking a hue and play around with saturation and lightness to create a color palette for your next website.