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.

CSS3 Transform Property and the various transform functions

The transform property

Supported in Firefox 3.5+. Opera 10.5 and Webkit since 3.1, the transform CSS property lets you modify the coordinate space of the CSS visual formatting model. Using it, elements can be translated, rotated, scaled, and skewed. We manipulate an elements appearance using transform functions. The value of the transform property is a list of space-separated transform functions applied in the order provided. The transform functions include:


The translate(x, y) function is similar to relative positioning, translating, or relocating, an element by x from the left, and y from the top.

  -webkit-transform: translate(15px, -15px); 
  -moz-transform: translate(15px, -15px);
  -o-transform: translate(15px, -15px); 
  transform: translate(15px, -15px);



The translateX(x) function is similar to the translate() function above, but only the left/right value is specified

  -webkit-transform: translatex(15px);
  -moz-transform: translatex(15px);
  -o-transform: translatex(15px);
  transform: translatex(15px);



The translateY(y) function is similar to the translate() function above, but only the top/bottom value is specified

  -webkit-transform: translatey(-15px); 
  -moz-transform: translatey(-15px); 
  -o-transform: translatey(-15px); 
  transform: translatey(-15px);


The scale(w, h) property scales an element by w width and h height. If only one value is declared, the scaling will be proportional. Since you likely don’t want to distort an element, you’ll generally see only one parameter in this transform function

  -webkit-transform: scale(1.5, 2);
  -moz-transform: scale(1.5, 2);
  -o-transform: scale(1.5, 2);
  transform: scale(1.5, 2);


The scalex(w) function is similar to the scale() function above, but only the width value is specified. It is the same as declaring scale(w, 1)

  -webkit-transform: scalex(0.5); 
  -moz-transform: scalex(0.5); 
  -o-transform: scalex(0.5); 
  transform: scalex(0.5);


The scaley(y) function is similar to the scale() function above, but only the height value is specified. It is the same as declaring scale(1, h)

  -webkit-transform: scaley(2);
  -moz-transform: scaley(2);
  -o-transform: scaley(2);
  transform: scaley(2);


The rotate(angle) function with rotate an element about the point of origin (described below) but the angle value specified.

  -webkit-transform: rotate(15deg); 
  -moz-transform: rotate(15deg); 
  -o-transform: rotate(15deg); 
  transform: rotate(15deg)


The skew(x,y) function specifies a skew along the X and Y axes. The x specifies the skew on the x-axis, the y specifies the skew on the y-axis. If there is only one parameter, then it’s the same as skew(x, 0), or skewX(x) . The values are angles: degrees, turns or grads.

  -webkit-transform: skew(15deg,  4deg);
  -moz-transform: skew(15deg,  4deg);
  -o-transform: skew(15deg,  4deg);
  transform: skew(15deg,  4deg);


The skewx(x) function is similar to the skew() value above, but only the x-axis value is specified. It is the same as declaring skew(x,0)

  -webkit-transform: skewx(15deg);
  -moz-transform: skewx(15deg);
  -o-transform: skewx(15deg);
  transform: skewx(15deg);


The skewy(y) function is similar to the skew() value above, but only the y-axis value is specified. It is the same as declaring skew(0,y).

  -webkit-transform: skewy(-6deg); 
  -moz-transform: skewy(-6deg); 
  -o-transform: skewy(-6deg); 
  transform: skewy(-6deg);

Multiple transforms

The above show single transforms, but you can include more than one transform on an element. To include more than one transform, simply separate them the tranform functions with spaces.

  .enlargen:hover {
  	-webkit-transform: translate(-50%, -50%) scale(2) rotate(0); 
  	-moz-transform: translate(-50%, -50%) scale(2) rotate(0);
  	-o-transform: translate(-50%, -50%) scale(2) rotate(0);
  	transform: translate(-50%, -50%) scale(2) rotate(0);

The above makes the element twice and tall and twice as wide. By translating the element 50% up and to the left, the bottom right corner should remain in the exact same location. The rotate(0) removes any possible rotation on the element.

This ‘enlargen’ class may be something you would want to add to an image gallery, hilighting an image that is hovered by making it four times larget (twice as wide and twice as tall) and remove any tilt that might have been interesting as a thumbnail but tacky in full size.

Win a FREE TICKET: 2nd Annual CSS Summit: July 28th

Win a free ticket to the online CSSSummit. Follow @estellevw on Twitter, and Tweet, facebook or blog that you want to go. Something like ““I wanna go to attend the online Follow @estellevw and retweet to win:” will work fine.

Can wait to sign up? Register at

I am very excited to be presenting at the 2nd Annual CSS Summit with some of the best speakers working with CSS today and a list of topics on the cutting edge:

  • Zoe Gillenwater, author of Stunning CSS, presents “CSS3 Techniques”
  • David McFarland, author of CSS: The Missing Manual, presents “CSS3 Animations”
  • Stephanie Sullivan, author of Mastering Dreamweaver and CSS, presents “CSS3 and Progressive Enhancement”
  • Jason Cranford-Teague, author of Fluid Web Typography, presents “CSS and Web Typography”
  • Denise Jacobs, author of The CSS Detective Guide, presents “Advanced CSS Troubleshooting”
  • Estelle Weyl, that’s me!, author of Beginning iPhone Web Apps, presents “CSS3 and iPhone Development”
  • Chris Eppstein, creator of CSS Compass framework, presents “CSS with SASS, SCSS & Compass”
  • Nicole Sullivan, curator of the Object Oriented CSS framework, presents “CSS and Optimizing Facebook”

Tell them Estelle sent you. Use discount code “CSSWEYL” for 10% off the 2nd Annual CSS Summit!

Join us for what is sure to be a great day of knowledge and insight with some of the Web’s leading experts in CSS.

There will be free recordings of the CSS Summit for all attendees. The online event is content-rich and allows for plenty of time for interaction with the speakers, but sometimes life gets in the way. They’ve upgraded their online conferencing software—now you can view (and review) recordings of the 2nd Annual CSS Summit at your own convenience in case work, vacation or nature calls, or in case we cover something that is new to you and you need to re-watch to fully grasp.

CSS3 only Native iPhone App. No images!

My challenge to myself today was to create the native look of an iPhone application using only CSS. No images. I did it. When developing for the iPhone, one only has to consider a single browser. This made the challenge somewhat easy.  The fun part was creating the page background, buttons and navigation bar without the use of image. Linear gradients came to the rescue.  Now that Safari 5 supports inset shadows, the buttons were a cinch.  Check it out (on iPhone or Safari 5 only)!

And, since I like to share, here are the important parts of the code:

        background-image: -webkit-gradient(linear, 0% 0%, 0% 50%, 
              from(rgba(176, 188, 205, 1)), to(rgba(129, 149, 175, 1)));
 	padding: 7px 10px;
	background-color: rgb(109, 132, 162);
	border-bottom-color:1px solid rgb(45, 54, 66);
	border-top:1px solid rgb(109, 132, 162);
	display: block;
	height: 31px;
	line-height: 30px;
	display: block;
	border-bottom: 1px solid #2C3542;
	border-top: 1px solid #CDD5DF;

#theBodyBackgroundImage {
      background-image: -webkit-gradient(linear, left top, right top, 
          color-stop(0.6, #C5CCD4), 
          color-stop(0.6, #CBD2D8));
     -webkit-background-size:7px 7px;
     background-repeat: repeat;

The page on it’s own is here, but is only decent on iPhone or Safari 5 and chrome.
The github version supports more browsers

Converting from HSL to RGB() & Hexadecimal Colors

I created a ‘spreadsheet’ of the HSL() (hue, saturation, lightness) colors. I noticed if you inspect the file in Firebug, the left hand console gives you the rgb() color, and the right hand inspector gives you the hexadecimal #RRGGBB color.

To translate a color from HSL() to RGB() or #FFF, visit the HSL() ‘spreadsheet’ and inspect the color in Firebug. Simple as that.

Of course, you don’t have to use my spreadsheet. Simply declare an inline hsl() value on a div in your own sandbox. Inspecting it in Firebug will give you both the rgb() value (in the left hand firebug console, inline on the element) and in the right hand console, under{} in the style console.

Hack for CSS3 Supporting Browsers

Implementing CSS3 features in your CSS file can be complex. You have to make sure that the CSS you’re feeding to FF3.5+, Chrome, Opera and Safari are not being read by FF2, IE6, IE7 and IE8. There’s a simple hack to make sure that your CSS3 is fed only to browsers that support it… it’s forward compliant and it’s valid markup.


To target all browsers that support CSS3, and hide from the IEs, simply add :nth-of-type(1n) to your selector.

  h3:nth-of-type(1n)  {
      color: #FFFFFF;
      background-color: #FFFFFF;
           3px 3px 3px rgba(0, 0, 0, 0.4);

In the above example, we’ll end up with white text on a white background, with the letters being defined by the drop shadow. You definitely don’t want to feed that to browsers that don’t support text-shadow: white text on white backgroud *IS* illegible.

:nth-of-type(1n) basically means “every”. So, it’s the same as not including it in terms of what selectors will be matched. Do note that you are adding a pseudo-class, so you are adding specificity. This pseudo-class is not understood by browsers that don’t support CSS3 selectors which is the same as those that don’t understand CSS3 properties and CSS3 property values.

For example, I have a row of images with captions going across a page. To make it more interesting, I made the pictures look like Polaroids. It looks fine plain, but why not add some fun CSS3.

/* understood by all browser */
.slides li {
	width: 188px;
.slides img {
/* for CSS3 supportive browsers only */
.slides li:nth-of-type(1n) {
	-moz-box-shadow:0 3px 6px rgba(0, 0, 0, 0.25);
	-webkit-box-shadow:0 3px 6px rgba(0, 0, 0, 0.25);
	box-shadow:0 3px 6px rgba(0, 0, 0, 0.25);
	background:none repeat scroll 0 0 #FFFFFF;
	margin:0 0 27px 0;
	padding:10px 10px 15px;
.slides li:nth-of-type(even){
.slides li:nth-of-type(3n){

The images look fine in IE, but look cool in FF3.6

Do make sure that the new CSS3 property is generally supported before using this hack. This is a general filter for generally supported CSS3. It works for multiple background images, text-shadow, border radius, and other well supported CSS3 properties and values. Don’t use this for CSS3 transitions, columns and animations until those are better supported in modern browsers. I have grids of browser support for all sorts of CSS3 properties, so take a look at those before relying on this filter.

CSS Color Formats and HSL

Prior to CSS3, we had 3 types of color formats: there was the hexadecimal format (and shorthand hex format), rgb() format and named colors. CSS3 adds support for HSL, HSLA and RGBA. Here are the formats we have in CSS3:

Color Syntax Example Definition
#RRGGBB #FF00FF hexadecimal format (tutorial)
#RGB #F0F shorthand hexadecimal format
rgb(r,g,b) rgb(255, 0, 255) red, green blue (tutorial)
hsl(h,s,l) hsl(300, 100%, 50%) hue, saturation, lightness
cmyk(c,m,y,k) cmyk(29%, 55%, 0, 0) Cyan, Magenta, Yellow, Black
hsla(h,s,l,a) hsla(300, 100%, 50%, 1) hue, saturation, lightness, opacity
rgba(r,g,b) rgba(255, 0, 255, 1) red, green, blue, opacity
named colors fuchsia see color name tutorial
transparent transparent no color (transparent)
currentColor currentColor color of the text for that element

In part I we discussed #RRGGBB, #RGB, rgb(), rgba() and touched upon HSL and HSLA colors. In this section we go further into HSLA, and discuss the new keyterm currentColor, and the color type that didn’t make it into the CSS3 specifications: flavor.

Hue, Saturation and Lightness

HSL stands for hue, saturation and lightness. The hue value in included in degrees from 0 to 359, with percentages for saturation and lightness, with 50% being the norm for lightness and 100% being the norm for saturation.

Lightness of 0% will be white, 50% will be the actual hue, and 100% will be black. Saturation of 100% will be the hue, and saturation of 0 will give you a shade of gray from white to #808080 to black depending on the lightness.

Values for hues include: 0 = red, 60 = yellow, 120 = green, 180 = cyan, 240 = blue, 300 = magenta, and everything in between. Each table below represents one hue. Twelve equally spaced colors (i.e.
at 30° intervals) have been chosen from the color circle: red,
yellow, green, cyan, blue, magenta, with all the intermediate colors (the
last is the color between magenta and red).

The X axis of each table represents the saturation (100%, 75%, 50%,

The Y axis represents the lightness. The higher the percent, the lighter the color is, the lower the percent, the darker, with 50% being ‘normal’. 100% lightness has been omitted from the tables below, since it’s always white, no matter the hue. Similarly, 0% lightness has been omitted, since it always renders black, no matter the hue.

0° (Red)






hsl(0, 100%, 88%)

hsl(0, 75%, 75%)
63 hsl(0, 100%, 63%) hsl(0, 75%, 63%) hsl(0, 50%, 63%) hsl(0, 25%, 63%)
50 hsl(0, 100%, 50%) hsl(0, 75%, 50%) hsl(0, 50%, 50%) hsl(0, 25%, 50%)

13 hsl(60, 100%, 13%) hsl(60, 75%, 13%) hsl(60, 50%, 13%) hsl(60, 25%, 13%)
30° (Orange)






hsl(30, 100%, 88%) hsl(30, 75%, 88%) hsl(30, 50%, 88%) hsl(30, 25%, 88%)

hsl(30, 100%, 75%) hsl(30, 75%, 75%) hsl(30, 50%, 75%) hsl(30, 25%, 75%)
63 hsl(30, 100%, 63%)
50 hsl(30, 100%, 50%)

hsl(30, 100%, 38%)
25 hsl(30, 100%, 25%)
13 hsl(30, 100%, 13%) hsl(30, 25%, 13%)
60° (Yellow)






hsl(60, 100%, 88%) hsl(60, 75%, 88%) hsl(60, 50%, 88%) hsl(60, 25%, 88%)

hsl(60, 100%, 75%) hsl(60, 75%, 75%) hsl(60, 50%, 75%) hsl(60, 25%, 75%)
63 hsl(60, 100%, 63%) hsl(60, 75%, 63%) hsl(60, 50%, 63%) hsl(60, 25%, 63%)
50 hsl(60, 100%, 50%) hsl(60, 75%, 50%) hsl(60, 50%, 50%) hsl(60, 25%, 50%)

hsl(60, 100%, 38%) hsl(60, 75%, 38%) hsl(60, 50%, 38%) hsl(60, 25%, 38%)
25 hsl(60, 100%, 25%) hsl(60, 75%, 25%) hsl(60, 50%, 25%) hsl(60, 25%, 25%)
13 hsl(60, 100%, 13%) hsl(60, 75%, 13%) hsl(60, 50%, 13%) hsl(60, 25%, 13%)
90° Yellow-Green
100% 75% 50% 25%
88 hsl(90, 100%, 88%)
75 hsl(90, 25%, 75%)
63 hsl(90, 100%, 63%) hsl(90, 75%, 63%) hsl(90, 50%, 63%) hsl(90, 25%, 63%)
50 hsl(90, 100%, 50%) hsl(90, 25%, 50%)
38 hsl(90, 25%, 38%)
25 hsl(90, 10%, 25%) hsl(90, 75%, 25%) hsl(90, 50%, 25%) hsl(90, 25%, 25%)
13 hsl(90, 25%, 13%)
120° (Green)






hsl(120, 100%, 88%) hsl(120, 25%, 88%)
75 hsl(120, 25%, 75%)
63 hsl(120, 25%, 63%)
50 hsl(120, 100%, 50%) hsl(120, 25%, 50%)
38 hsl(120, 100%, 38%) hsl(120, 75%, 38%) hsl(120, 50%, 38%) hsl(120, 25%, 38%)
25 hsl(120, 25%, 25%)
13 hsl(120, 25%, 13%)
150° Green-Cyan

100% 75% 50% 25%

hsl(150, 100%, 88%) hsl(150, 75%, 88%) hsl(150, 50%, 88%) hsl(150, 25%, 88%)
75 hsl(150, 100%, 75%) hsl(150, 75%, 75%) hsl(150, 50%, 75%) hsl(150, 25%, 75%)
63 hsl(150, 100%, 63%) hsl(150, 75%, 63%) hsl(150, 50%, 63%) hsl(150, 25%, 63%)
50 hsl(150, 100%, 50%) hsl(150, 75%, 50%) hsl(150, 50%, 50%) hsl(150, 25%, 50%)
38 hsl(150, 100%, 38%) hsl(150, 75%, 38%) hsl(150, 50%, 38%) hsl(150, 25%, 38%)
25 hsl(150, 100%, 25%) hsl(150, 75%, 25%) hsl(150, 50%, 25%) hsl(150, 25%, 25%)
13 hsl(150, 100%, 13%) hsl(150, 75%, 13%) hsl(150, 50%, 13%) hsl(150, 25%, 13%)
180° (Cyan)

100% 75% 50% 25%

hsl(180, 100%, 88%) hsl(180, 50%, 88%) hsl(180, 25%, 88%)
75 hsl(180, 75%, 75%) hsl(180, 25%, 75%)
63 hsl(180, 100%, 63%) hsl(180, 50%, 63%) hsl(180, 25%, 63%)
50 hsl(180, 100%, 50%) hsl(180, 75%, 50%) hsl(180, 25%, 50%)
38 hsl(180, 100%, 38%) hsl(180, 50%, 38%) hsl(180, 25%, 38%)
25 hsl(180, 75%, 25%) hsl(180, 25%, 25%)
13 hsl(180, 100%, 13%) hsl(180, 50%, 13%) hsl(180, 25%, 13%)
210° Cyan-Blue

100% 75% 50% 25%

hsl(210, 100%, 88%) hsl(210, 75%, 88%) hsl(210, 50%, 88%) hsl(210, 25%, 88%)
75 hsl(210, 75%, 75%) hsl(210, 25%, 75%)
63 hsl(210, 100%, 63%) hsl(210, 50%, 63%) hsl(210, 25%, 63%)
50 hsl(210, 100%, 50%) hsl(210, 75%, 50%) hsl(210, 25%, 50%)
38 hsl(210, 100%, 38%) hsl(210, 50%, 38%) hsl(210, 25%, 38%)
25 hsl(210, 75%, 25%) hsl(210, 25%, 25%)
13 hsl(210, 100%, 13%) hsl(210, 50%, 13%) hsl(210, 25%, 13%)
240° (Blue)

100% 75% 50% 25%

hsl(240, 100%, 88%) hsl(240, 25%, 88%)
75 hsl(240, 100%, 75%) hsl(240, 75%, 75%) hsl(240, 50%, 75%) hsl(240, 25%, 75%)
63 hsl(240, 25%, 63%)
50 hsl(240, 100%, 50%) hsl(240, 25%, 50%)
38 hsl(240, 100%, 38%) hsl(240, 75%, 38%) hsl(240, 50%, 38%) hsl(240, 25%, 38%)
25 hsl(240, 25%, 25%)
13 hsl(240, 25%, 13%)
270° Blue-Magenta

100% 75% 50% 25%

hsl(270, 100%, 88%) hsl(270, 75%, 88%) hsl(270, 50%, 88%) hsl(270, 25%, 88%)
75 hsl(270, 25%, 75%)
63 hsl(270, 25%, 63%)
50 hsl(270, 100%, 50%) hsl(270, 25%, 50%)
38 hsl(270, 25%, 38%)
25 hsl(270, 25%, 25%)
13 hsl(270, 100%, 13%) hsl(270, 75%, 13%) hsl(270, 50%, 13%) hsl(270, 25%, 13%)
300° (Magenta)

100% 75% 50% 25%

hsl(300, 100%, 88%) hsl(300, 75%, 88%) hsl(300, 50%, 88%) hsl(300, 25%, 88%)
75 hsl(300, 100%, 75%) hsl(300, 75%, 75%) hsl(300, 50%, 75%) hsl(300, 25%, 75%)
63 hsl(300, 100%, 63%) hsl(300, 75%, 63%) hsl(300, 50%, 63%) hsl(300, 25%, 63%)
50 hsl(300, 100%, 50%) hsl(300, 75%, 50%) hsl(300, 50%, 50%) hsl(300, 25%, 50%)
38 hsl(300, 100%, 38%) hsl(300, 75%, 38%) hsl(300, 50%, 38%) hsl(300, 25%, 38%)
25 hsl(300, 100%, 25%) hsl(300, 75%, 25%) hsl(300, 50%, 25%) hsl(300, 25%, 25%)
13 hsl(300, 100%, 13%) hsl(300, 75%, 13%) hsl(300, 50%, 13%) hsl(300, 25%, 13%)
330° Magenta-Red

100% 75% 50% 25%

hsl(330, 100%, 88%) hsl(330, 25%, 88%)
75 hsl(330, 25%, 75%)
63 hsl(330, 25%, 63%)
50 hsl(330, 100%, 50%) hsl(330, 25%, 50%)
38 hsl(330, 100%, 38%) hsl(330, 75%, 38%) hsl(330, 50%, 38%) hsl(330, 25%, 38%)
25 hsl(330, 100%, 25%) hsl(330, 75%, 25%) hsl(330, 50%, 25%) hsl(330, 25%, 25%)
13 hsl(330, 25%, 13%)

There is a grid with many more colors at if you want to see how more hsl combinations render and have a browser that supports HSL rendering. The grid above is coded with hexadecimal colors, since internet explorer does not understand HSL colors. The grids at require Opera, Safari, Firefox, Chrome or IE9 to view.


Similar to rgb() with rgba(), hsl() also has an alpha transparent call, hsla(). The syntax is hsla, followed by hue in degrees, saturation in percentage, lightness in percentage and alpha value from 0-1, encompassed in parenthesis.

For example: hsla(300, 100%, 50%, 0.5) is magenta at 50% opacity.

CSS3 Implementable Features

There are several features of CSS3 that are implementable today. In this presentation we discuss CSS3 Selectors, Text Shadows, Box Shadow, Rounded Corners (prefixed), @font-face, Alpha Transparency, Opacity, Rotation. Mostly, there are links to my sandboxing of those features.

If it’s not successfully embedded, you can see it here css3 implementable features

Content covered in the PPT presentaion

I do not have a podcast, but here is a summary of what was presented in case you missed it, or incase the flash above isn’t enough

CSS3: Si se puede


has been around since 1999, but only fully supported in IE8. We obviously didn’t wait to implement CSS2 until all the browsers fully supported it. CSS3, while not yet finalized, has a lot of features that are supported in many browsers. Like CSS 2.1, there is no reason not to use these features just because not all browsers support all the features equally: if that were our logic, we would still be on CSS1.

Your site does not need to be identical in all browsers

In developing with CSS3 think about graceful degradation. Not all browsers need to implement your site identically. Yes, your site should look good in all browsers, but no, if your body is a few pixels different in one browser to the next, who cares? You’re the only one who is going to be looking at your website in multiple browsers at the same time. 99.99% of the site user base (that number is pulled out of my ass) have one favorite browser on their desktop, and that’s what they’ll use to look at your site.

Twitter uses rounded corners for non IE browsers only

Example: Twitter uses native rounded corners for supporting browsers.

IE does not support rounded corners. Twitter believes that rounded corners make their site look nicer, but lack of them doesn’t break the site. So, the experience is a little different in the IE’s than in modern browsers. But if I hadn’t shown you this example, you may never have known!

Twitter would have had a difficult time creating rounded corners with images since the background color of the right hand nav bar on twitter is user selectable. They could have created rounded corners on the left and square angles on the right, but likely going all square for IE looked better.

For the rest of the examples, I’ll be explaining how to make CSS3 work in IE. I just want to spread the gospel that it doesn’t have to look identical anyway.

Features that are implementable and discussed below:

  • CSS3 Selectors
  • Text Shadow (2.0).
  • Box Shadow (prefixed)
  • Rounded Corners (prefixed).
  • @font-face
  • Alpha Transparency.
  • Opacity.
  • Rotation.

Features that are implementable, but not discussed in this talk

  • Multi-column layout
  • Video (HTML5)
  • Animations
  • Transitions
  • Border-image
  • Multiple background images
  • Linear Gradients

CSS3 Selectors

If you look at the grid of CSS3 Selectors and Browser Support, you’ll note that, at this point, only the three IEs don’t understand CSS3 selectors. That doesn’t mean you can’t use them.

To see all the selectors, and what you can and cant use, check out CSS3 Selectors and Browser Support

Alpha Tranparency

color: rgba(0,0,0,0.4);
color: hsla(300, 100%, 50%, 0.4);

HSL stands for hue, saturation and lightness. The HSL format simplifies color palette creation as you can pick a hue as the base, then manipulate the lightness/darkness and saturation of the hue selected.

HSL is a new color type added in CSS3, stading for hue, saturation and lightness. The syntax is similar to rgb(), but instead of including the values for red, green and blue, the color value accepts values in degrees from 0 to 359 for hue, and percentages for saturation and lightness, with 50% being the norm for lightness and 100% being the norm for saturation. Lightness of 0% will be white, 50% will be the actual hue, and 100% will be black. Saturation of 100% will be the hue, and saturation of 0 will give you a shade of grey from white to #808080 to black depending on the lightness.

Values for hues include: 0 = red, 60 = yellow, 120 = green, 180 = cyan, 240 = blue, 300 = magenta, and everything in between.

Similar to rgb() with rgba(), hsl() also has an alpha transparent call, hsla(). the syntax is hsla, followed by hue in degrees, saturation in percentage, lightness in percentage and alphavalue from 0-1, encompassed in parenthesis.

For example: hsla(300, 100%, 50%, 0.5) is magenta at 50% opacity.


Opacity likely doesn’t have the impact you intended. The element made less that fully opaque is not the only element impacted. All the element with a z-index higher than the one made opaque inherit the same level of transparency. Generally, you’ll want to use alpha transparency on a background rather than opacity.

  .halfthere {
       opacity: 0.4;
       filter: alpha(opacity=0.4)

Opacity Example

Rounded Corners

.rounded {
      -moz-border-radius: 3px;
      -webkit-border-radius: 3px;
      border-radius: 3px;

The order is topleft, topright, bottomright, bottomleft.

Safari has some issues with rounded corners.

IE6, IE7 and IE8 don’t support native CSS rounded corners, and never will. For those browsers, if I really don’t want my page to look different in the IEs than in modern browsers, I add the rounded corners with a little bit of JavaScript and CSS magic, and a single background image:

$('.rounded').append('<b class="tr"></b><b class="tl"></b><b class="br"></b> <b class="bl"></b>');

Text Shadow

.shadowed {
  text-shadow: 3px 3px 3px rgba(0,0,0,0.4);

In the above, the order of values is

leftOffset rightOffset blur Color

If you’re going to use text shadow, which is not supported in IE, this is a good time to use the Hack for CSS3 Supporting Browsers. As I mention in that article, you don’t want to end up with white text on white background.


Transforms are supported in all browsers, just with different syntax.

    -webkit-transform: rotate(90deg);
    -moz-transform: rotate(90deg);
    -o-transform: rotate(90deg);
    transform: rotate(90deg);
    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);

Note that for IE, the values are 1=90, 2=180, 3=270. Check out my

sandbox, or just look at the header of this blog.

I’ve been told that IE supports more than just the 90degree angles, but haven’t tested yet. The syntax is:

     filter:  progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand',
                     M11=6.123233995736766e-17, M12=-1, M21=1, M22=6.123233995736766e-17); /* for IE6 and IE7 */
         -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(SizingMethod='auto expand',
                     M11=6.123233995736766e-17, M12=-1, M21=1, M22=6.123233995736766e-17)"; /* for IE8 */

and make sure that the element hasLayout.


I didn’t actually go over gradients in my presentation, but linear gradients are  supported in one way or another in all browsers except opera, so you can use them. Radial gradients …. not yet.

background-image: -moz-linear-gradient(top, #56abf3, #ffffff, #ffffff, #ffffff); /* FF3.6+ */
background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #56abf3),color-stop(25%, #ffffff));

IE has

Filter: progid:DXImageTransform.Microsoft.gradient (GradientType=0, startColorstr=#FF56abf3, endColorstr=#FFFFFFFF)

There are two types of Gradients – 0 gives a gradient running from top to bottom. 1 from left to right.
startColorstr —  The start color of the gradient. The first 2 characters in the 8 digit HEX color number are the Alpha values ( 00 being transparent,  FF is opaque). Default is blue
endColorstr= —   The color of the bottom or right  end of the gradient, depending on what GradientType you use. The default color is black  #FF000000 if omitted.

There are no colorstops in IE as far as i can tell