Multiple Borders via CSS box-shadow

Update : Multiple box-shadows now work in Chrome 5 as well as in Firefox 3.5+, although in the examples with border radius, each successive shadow becomes more and more squared off; see Chrome screenshots 1 & 2 below.

To make multiple borders appear around an element, the traditional approach has been to nest multiple elements and apply a different border to each. For example, to put a rainbow border on an element:

I have rainbow borders!

This approach uses seven div elements. However, there is an alternative that avoids the need for so many superfluous elements: the new CSS3 box-shadow property. A key feature of this property is that it allows for multiple shadows to be supplied at once:

box-shadow: none | <shadow> [ , <shadow> ]*

When multiple shadows are supplied, they can be positioned on top of each other to create a multiple-border effect. Using the box-shadow property in this way requires support for the "spread radius" value, and this is not currently supported by WebKit (includes Safari and Chrome). However, Firefox 3.5 (now available as a preview release) does support the box-shadow spread radius, and if using that browser, the following example should look identical to the example above:

I have rainbow borders!

Using box-shadow for multiple borders not only eliminates the need for extra markup, it also allows the multiple borders to be easily rounded on corners simply by adding the border-radius property (see screenshot from Firefox 3.5, and another from Chrome 5):

I have rainbow borders with rounded corners!

To accomplish the same above with multiple nested elements, you would have to tediously increase the border-radius for each wrapped element in order to get the corner arcs to fit together properly.

I suppose using box-shadow to implement borders is a kind of hack (the technique requires setting margins because the shadows don't effect page flow), but we're celebrating the compeltion of Firefox 3.5 by showcasing hacks like these! It would be great if multiple borders could simply be specified on a border property just as is possible with box-shadow. Each subsequent border defined could wrap around the previously defined borders. The property could be defined:

border: none | <border> [ , <border> ]*

In any case, the box-shadow property still has a benefit of allowing the borders to blend together by specifying the box-shadow's blur radius (see screenshot from Firefox 3.5 and another from Chrome 5):

I have blended rainbow borders!

It's exciting to see how Mozilla is implementing bleeding-edge CSS features in Firefox as we have become accustomed to from the WebKit team. Great work everyone!

3 thoughts on “Multiple Borders via CSS box-shadow

  1. It’s such a shame we still have to take into account old browsers (even IE8 is an old browser by now!)

    But in a personal page, I have no problem with asking users to view it in FF/Opera/Webkit browsers with little to no IE fallback

  2. This is really cool, but still not quite as flexible as I’d like. The effect I want still seems to require extra markup if I don’t want it to look really terrible in older browsers (even accounting for graceful degradation). If only I could just specify a “content border” that is inside the padding… That’s all I need in this case.

    This technique doesn’t even seem to work in Safari 4 (all the shadows blend together), so I’m probably going to hold off for now.

Leave a Reply