CSS 3 and The Future: Image-free Rounded Corners, Drop Shadows and Gradients

Rounded Corners (Were) Hard.

If you build web things, then you know how difficult it can be to try hacking a non-square thing into the web's square-dominated CSS box model. Attempting to make a flexible, let alone fixed-width box appear to have rounded corners, drop shadows or gradients is an exercise in frustration.

It's no secret that rounded corners are a huge point of contention amongst web developers, with feelings mixed between both passion and hatred. It is truly a love/hate relationship. Years ago, a co-worker at Yahoo! had surmised that one of the most common lunch-time discussion topics was debating the "best", or least-crappy, way to have a link, button or <div> display with rounded corners in A-grade browsers - taking into account the number of images (if any), markup weight, flexibility in font size and design, code cleanliness and so on.

Searching the web reveals countless approaches, two of my own attempts included, to make rounded corners "just work" using CSS 2 and balancing the number of images, code weight and CSS hackery (and in some cases, even Javascript) required to make it all happen. The number and variety of solutions out there alone gives an idea of the complexity of the problem.

The Old-Skool (CSS 2) Way

Even more rounded corners with CSS: Example image

Revised (2007) single-image approach to fluid width/height rounded corners, drop shadows and gradients also including alpha opacity via PNG.

Rounded corner dialogs with CSS - example of how the image is cut

Old-skool (2006) approach to rounded corners, drop shadows and gradients using a form of Sliding Doors + Standard Module Format.

Back in 2003 a creative guy known as Doug Bowman came up with the Sliding Doors CSS technique, an approach using two HTML elements to provide the left and right placeholders for background images fulfilling endless variants of fluid, flexible designs including rounded corner effects for tabs, dialogs and buttons. This approach has been used for years to achieve these sort of effects, but CSS 3 may finally make it obsolete.

What was previously done with background images can be rendered purely with CSS 3 for the most part, reducing or altogether eliminating extraneous markup placeholder <div> elements and simplifying the effect to a single stylesheet rule.

For getting that rounded corner look with CSS 3, what used to involve background images and endless hacks can now be simplified to border-radius. Instead of a drop shadow sprite or separate t/r/b/l images, you can use box-shadow. It's like magic!

Let The Squares Be Square.

Old and "not-cutting-edge" browsers will simply ignore this foreign, newfangled border-radius stuff, and will render boxes with 90-degree corners. This is OK, as that's how the web should work. Modern browsers get modern features; browsers that aren't hip, are.. square. Thank you, thank you, I'll be here all evening.

Also:

The success of your design should not hinge on these features.

No site "requires" rounded corners or drop shadows as essential design elements; rather, they should be considered as enhancements to a basic user experience. If CSS 3 is supported, great; the browser will happily render a shinier UI. If not, the experience will be simpler, but still functional: A basic tenet of "progressive enhancement." Let the squares be square!

Doing things the old way just because they work is not also a great practice. The "old-skool" approach is error-prone, expensive to develop and to maintain. It hurts site performance and load time, adds a lot of bloat to the code, introduces risk of more bugs and is completely unnecessary given these features are now available "for free", capable of being rendered natively by a growing number of browsers.

While browser support for CSS 3 is growing at the time of writing (Firefox and Safari/Webkit have supported forms of border-radius since 2007-ish, and Opera 10's dev version has just added it), Internet Explorer 8 does not support this and other desirable "cutting-edge" CSS 3 features. My hope is IE 9 will include border-radius, at the least.

Reaching Enlightenment: The Modern, CSS 3 Way

CSS 3 introduces a number of new features that significantly reduce the amount of work required to get desirable UI stylings, rounded corners being one of them. Not all browsers implement these features, and some have their own vendor-specific prefix as the support for the feature may not be considered complete or to the published spec. Therefore, some require -moz- or -khtml- prefixes, for example. When finalised, the standard property should be used in place of the prefixed version.

border-radius

Finally! Rounded corners, effort required is "free" compared to all the old crazy hacks! Radius can be defined in ems, px etc. Works in Firefox 2.x, Safari 3, Chrome, Opera 10 (dev build as of 09/2009.) The examples here use CSS -prefixes in all cases, though they may be omitted on-screen for brevity.

border:3px solid #999;
padding:1em;
-moz-border-radius:8px;
-webkit-border-radius:8px;
-opera-border-radius:8px;
-khtml-border-radius:8px;
border-radius:8px;
border-radius:32px;

Note that if your browser doesn't support border-radius or doesn't like a certain radius value, the above will simply have square corners. This is a good thing, and is how "progressive enhancement" works. If you're seeing square stuff now, you can see a CSS 3 demo screenshot from Safari 4.

It's worth mentioning that some earlier browsers do not render border-radius with anti-aliasing, notably older versions of Chrome and Firefox. They should be a small number of active browsers, however.

Related: border-radius and -moz-border-radius

box-shadow / text-shadow

Draws a drop shadow underneath an element with horizontal and vertical offsets, and blur. Supports alpha opacity as well, can produce effect similar to Photoshop's drop shadow. Supported in Firefox 3.5 and Safari 3.0 (522) at time of writing (September 2009.)

box-shadow:rgba(0,0,0,0.5) 0px 0px 24px;

A slight variant, with border-radius as well:

box-shadow:rgba(0,0,0,0.5) 0px 0px 24px; border-radius:12px;

In addition to box-shadow, text-shadow is a related new CSS 3 property which allows drop shadows on text. Below, if supported, will be a rather gratuitous example.

color:#6699ff; text-shadow:0px 0px 10px #99ccff

Related: css3.info, screenshots and examples / developer.mozilla.org, -moz-box-shadow documentation/examples / "Rainbow borders" via box-shadow, interesting demo

Bonus: CSS gradients

Currently, CSS gradients are supported in Safari and Firefox 3.6 as -webkit-gradient, -moz-linear-gradient. They appear to be part of the CSS 3 working draft and therefore should be considered experimental and subject to change at this time, but are nonetheless interesting and potentially useful if you want to make shiny, glossy buttons and the like without resorting to using images.

border:4px solid #000;
background-color:#000;
background-image:-webkit-gradient(linear, 0% 1%, 0% 95%, from(rgba(255,255,255,0.9)), to(rgba(64,64,64,0.9)), color-stop(.8,rgba(64,64,64,0.25)),color-stop(.25,rgba(32,32,32,0.5)));
background-image:-moz-linear-gradient(top,bottom,from(rgba(255,255,255,0.9)),color-stop(80%, rgba(64,64,64,0.25)),color-stop(25%, rgba(32,32,32,0.5)),to(rgba(64,64,64,0.9)));

Related: Westciv gradient tool (live adjustable -webkit-gradient demos), webkit.org: CSS gradients / -moz-linear-gradient (developer.mozilla.org)

Tying It All Together: Glossy Buttons

Now that we have rounded corners, drop shadows and gradients, we can combine them together to make a gratuitously-shiny button example. It should be shiniest under Safari 4 and Firefox 3.6, currently in alpha development.

Click me!
Click me!
Click me!

A Thank-you

This glossy button idea was originally developed by GirlieMac!, whose work I found while doing research for this article; she did an excellent job of recreating OS X's gloss style using CSS gradients. This demo is based off of her implementation, but should also work under Firefox 3.6a.

Miss The Demos?

If your browser doesn't do some of the fancy effects and you want to see how it was supposed to look, see this CSS 3 demo screenshot from Safari 4.

Related links