While fiddling around with the CSS3 box-shadow property, I stumbled across a method to put a double border on a single element. I thought to myself, that’s pretty cool, but obviously, it will only work in newer browsers that support box-shadow.
So I wondered how many different ways there are to create an element that has the appearance of a double border. Naturally, the most common way is by using a non-fluid background image. But that’s obviously not ideal.
So, I’ve compiled five different methods for doing this. Only one requires use of an image; the rest are pure CSS, with pretty good browser support for all methods. For brevity, in the code examples I’ve removed the common stuff like width, height, background, etc. You can view all the examples on the demo page:
Method 1: Border and Outline
This method will only work on browsers that support the outline property, so that means everything but IE6/7. Basically, you add a border using both the border and outline properties. Here’s the CSS, not including the stuff that’s common to all the examples (like width, float, background, etc):
.one {
border: solid 6px #fff;
outline: solid 6px #888;
}
The reason it works is because an outline is always placed outside of the box. The problem with the outline property is that it doesn’t affect the flow of elements around it, so it will overlap or underlap other elements, so that could be undesirable.
Method 2: A Pseudo-Element
This one’s a bit tricky, because it requires (from what I can tell) absolutely positioning the border—which would seem to make it non-fluid. Well, using a bit of trickery, I was able to make this method work and be vertically fluid. Here’s the pertinent code:
.two {
border: solid 6px #fff;
position: relative;
z-index: 1;
}
.two:before {
content: "";
display: block;
position: absolute;
top: -12px;
left: -12px;
border: solid 6px #888;
width: 312px;
padding-bottom: 12px;
min-height: 100%;
z-index: 10;
}
The key parts are the z-index settings (to keep the pseudo-element from overlapping the content), the positioning, and the min-height value. The latter keeps the fluidity intact.
Method 3: Box Shadow
As mentioned, the idea for this experiment was the result of serendipitous fiddling with box-shadow settings. I personally like this one the best, because it’s just one line of code, and it uses a new technology in an unexpected way.
.three {
box-shadow: 0 0 0 6px #fff, 0 0 0 12px #888;
}
To make the shadow appear like a double border, I’m using two shadows (comma separated) and I’ve set the offset and blur settings to zero, while giving each shadow an appropriate size. Because one overlaps the other, the second shadow is twice the size of the other. The key parts are the lack of blur and a fully opaque color. This gives each shadow a straight edge, just like a border.
Just like the outline property, box-shadow will not impact elements around it, so you might have to fiddle with margins to position it so that it looks like a regular box with a border.
Naturally, this is limited to browsers that support box-shadow.
Method 4: An Extra Div
This method nests an extra <div> to give the appearance of a double border. This is the only one of these methods listed here that works everywhere (although even this one looks a bit whacked in my demo in IE6/7 because of margin settings, but that can be corrected). Not much else to say about this one, just a natural use of borders and backgrounds:
.four {
border: solid 6px #888;
background: #fff;
width: 312px;
min-height: 312px;
}
.four div {
width: 300px;
min-height: 300px;
background: #222;
margin: 6px auto;
overflow: hidden;
}
The styles for this method would vary depending on the size and context of the box, but as you can see, the outer box is 12 pixels bigger than the inner box, to accommodate the space that lets the background peek through, giving the illusion of two borders on a single element.
Method 5: Border Image
Another modern-browser method, this one uses the often-forgotten CSS3 border-image property:
.five {
border-width: 12px;
-webkit-border-image: url(multiple-borders.gif) 12 12 12 12 repeat;
-moz-border-image: url(multiple-borders.gif) 12 12 12 12 repeat;
border-image: url(multiple-borders) 12 12 12 12 repeat; /* for Opera */
}
For an explanation of border-image see this post on SitePoint.
Any Other Methods?
I couldn’t think of any other methods to do this, so somehow I feel like I’ve overlooked something obvious. I’m sure someone will point it out if I have.
I’ve put all the methods in a demo page along with some JavaScript that will allow you to add and remove content from each box, so you can see that the box is not restricted to a single height.

Well there is the obvious (to me)
border-style: doublebut that’s pretty limited in what you can do. Basically 3 borders with 2 colours (if you include the background).I was thinking that you should be able to do something with gradients and color-stops but maybe that’s just for backgrounds. In theory you can do a border on one side of a box, or two opposite sides, using a background.
Nice, I didn’t realize there was a “double” value for
border-style. But yeah, pretty limited, but I suppose it’s an option depending how the different browsers display it.It shoul be as easy as
It isn’t unfortunately.
Well, I just used it playing with padding! My div had a single (non-transparent) image inside, so I just used a padding:5px; with a background-color:#your-color; … And the border just wraps around this div! Simple but effective.
I agree, this is the best method. No extra elements and the least amount of code.
I’m on my way out right now but I’ve got for you a quick idea to consider: CSS3 box-sizing property.
Would be awesome if you could do:
Through infinity, or what have you…
Actually you can, by using box-shadow instead of border.
adding images as borders got my attention, as for the big picture, I prefer playing with the padding. why replace it if it is not broken?
keep them coming!
Here’s an article I wrote as a response: http://www.itmitica.com/en/articles/css3/m-borders/
I’ve used nested divs as markup and display: table-cell as style to build a model that allows for multiple legitimate borders.
Obviously I’m one of those developers: I don’t think I need to cover for older browser for stuff like this.
Well, the nesting makes it quite unusable, but I’m wondering if there’s something inherent in using
display: table-cellto get multiple borders to work. I’ve never played around with those display values, so I’m really not sure off the top of my head.I’m not sure why you’re saying the nesting makes it unusable. div nesting as a CSS practice has been around for quite some time: rounded corners, sliding doors etcetera.
On the plus side, you get real borders that behave and accept real border properties, including CSS3 newest border properties.
As for display: table-cell, it works perfectly fine, except for older browsers like IE7, a problem that can be solved with some extra effort.
I’ve updated the article: http://www.itmitica.com/en/articles/css3/m-borders/ in an attempt to answer your question about inherent behavior. Let me know if I’ve understood correctly your question.
I think it’s not as usable, because you’re nesting a lot of divs, but you have a lot more borders on that one, so it’s understandable. I think in that case, it might be better to choose something like box-shadow, while falling back to a simpler border for IE. Or else just use images.
Anyhow, thanks for the feedback and for the example.
No problem, just my two cents on the matter.
One last thing. Your example using divs presented some margin problems. The real gain with using display: table-cell is that I don’t have to worry about margins even when I decide to go with fixed width.
You’ve got a serious case of divitis. I would stay away from doing it like that. It’s like saying “but tables for layout work, so why do it differently?”. It’s bad for maintainability and semantically it makes no sense.
Hi Daan.
I’m not sure how closely you’ve looked at my example or how well you’ve read the observations. I’ve used an exaggerated number of divs, four, just to outline the model. I can’t think of a scenario requiring four borders on an element. So I have to disagree, it’s not remotely close to a divitis scenario.
Further more, if you’re looking for semantics in a CSS styling model that’s using divs, you’re in bad luck. Certainly I’m not trying to convey any meaning with my multiple borders construct, and certainly I can’t think of other suitable elements for my CSS multiple borders construct.
HTML5 specs, much like HTML 4 / XHTML 1.0 specs, still have to say this about the div element: “The div element has no special meaning at all. [...] Authors are strongly encouraged to view the div element as an element of last resort, for when no other element is suitable.”
Finally, you’re getting a little weird here. I’m not sure I understand your tables for layout reference in this context. display: table, display: table-cell are powerful CSS (as in style) tools that have nothing to do with HTML (as in markup) tables past misuse.
Daan, here’s an instructive article by a fellow Canadian of yours “It’s not divitis” http://snook.ca/archives/html_and_css/its_not_divitis/ you may find useful. It’s quite old, but so are your concerns.
I love the smartness and simplicity of method three, but on balance I’ll plumb for method one – and ie6/7 be damned. Great tinkerings!
I kbnow that Mozilla supports border gradiants as I added them to my site last year. My URL so you can see it is:
http://www.simonday.com/web-design-blog/
The code is:
I believe that Chrome also now supports it but I haven’t looked into it yet.
Thats pretty cool, but what can i do, if I need a top-border on my site? Your examples shouldnt work in this case, or?
Beat me to it guys my favourite and great for most images. Solid in ie also
Jimmy
Awesome, thanks!
I used the double div solution. Basically this code is for two-1px borders. Works for me. Not too sure how the code handles in IE6/IE7, but seems fine in everything else (for the purpose I’m using it for).
#icons_container {
border: 1px solid #a95759;
padding: 1px;
}
#icons {
width: 100%;
height: 100%;
background: #aa5958;
}
This is definitely the most exhaustive list on the net about ways of creating multiple borders in CSS. I thought that border-radius in itself supports multiple border, but seems that we still need to use some hacks to get to the result.
Thanks.
This is actually what I was looking for. Thanks!
method 1 is good, because its ver short and simple. but a have a problem with it: border radius works inside the outline and dont looks good. without border radius if the element dont needs border radius its cool
Good point! Actually, the first method and the last method would both not be able to use border-radius. The other ones can use border-radius, but you need to get the nested radii right.
Thanks for the post! I found this pretty helpful. I actually ended up using a combination of a couple of your examples to achieve the desired effect.
border: solid 2px #ccc;
box-shadow: 0 0 0 10px #ccc;
outline: solid 8px #fff;
Excelent! I liked the third way too. Thanks a lot.