Using pseudo element(s)
You can position a pseudo element such that it’s either behind the element, and larger, making a border effect with it’s own background, or smaller and inside (but make sure the content gets positioned on top).
The element needing multiple borders should have its own border and relative positioning.
.borders {
position: relative;
border: 5px solid #f00;
}
The secondary border is added with a pseudo element. It is set with absolute positioning and inset with top/left/bottom/right values. This will also have a border and is kept beneath the content (preserving, for example, selectability of text and clickability of links) by giving it a negative z-index value. Careful with negative z-index, if this is within yet another element with it’s own background color, this may not work.
.borders:before {
content: " ";
position: absolute;
z-index: -1;
top: 5px;
left: 5px;
right: 5px;
bottom: 5px;
border: 5px solid #ffea00;
}
See the Pen gbgRqZ by Chris Coyier (@chriscoyier) on CodePen.
You can do a third border by using the :after
pseudo class as well. Take special note that Firefox 3 (pre 3.6) screws this up by supporting :after
and :before
, but not allowing them to be absolutely positioned (so it looks weird).
Using outline
While it’s a bit more limited than border (goes around entire element no matter what) outline is a extra free border.
.borders {
border: 5px solid blue;
outline: 5px solid red;
}
Using box-shadow
You can use box-shadow to make a border effect, by making the the shadow offset and have 0 blur. Plus, by comma-separating values, you can have as many “borders” as you like:
.blur {
box-shadow:
0 0 0 10px hsl(0, 0%, 80%),
0 0 0 15px hsl(0, 0%, 90%);
}
See the Pen xbgreX by Chris Coyier (@chriscoyier) on CodePen.
Using a clipped background
You can make the background of an element stop before the padding. That way an elements normal border can look like a double border in a way.
.borders {
border: solid 1px #f06d06;
padding: 5px;
background-clip: content-box; /* support: IE9+ */
background-color: #ccc;
}
On an input:
See the Pen Double border effect on <input> by Chris Coyier (@chriscoyier) on CodePen.
So glad you have things here that should be obvious but elude the brain during the days work. Thanks Chris – appreciated
Hm,
I am searching for a short way to make a div box look indent, so I stumbled upon this post. I thought it would help me getting those indent think to work, but it looks weird in Firefox and doesn’t work in IR. I used a method which is combining the border- and the outline-properties which works fine in Firefox but not in IE. Any suggestions?
Thanks for this post, Chris – very interesting.
I played around with this today (my first foray into using pseudo-elements).
But I had to adjust the size, margins, and padding of the :before pseudo-element using tedious trial-and-error. Haven’t figured out the required math to avoid trial-and error in the future, but was pleased I finally got it working.
I think this works a little better with negative positioning on the pseudo element. You can then have a background color on the box itself, and a margin negating the positioning of the pseudo element.
Degrades a little more gracefully
It isn’t a multiple border thing, but I figured this out because of this page so I thought I’d share it here. I had not previously caught that you can do the multiple shadow thing and had been going crazy trying to figure out how to do a CSS only bevel on a button. Thanks to you I can now!
This looks really nice. I played around with it for a while and ended up adding an active flag to make a neat button press effect. Padding is used to push the contents down and left 1 pixel from the original padding.
Chris, I think using box-shadow is a little far from being semantic. I mean, after all, what we write should be what users would expect semantically, if they could understand our code. Imagine somebody is reading your code, and encounters
I think he expects to see a shadow (or a glow) in your site, not a solid, border-like outline.
There is no such thing as “semantic CSS”. CSS is presentation and markup is semantic. There has been a long struggle to separate the two. There is no such thing as “semantic aesthetics”.
Well, the example you gave is in fact a shadow or glow, not solid outline.
I guess you meant
which gives a solid, 3 pixel outline.
And if a user understands CSS, he will know this and expect accordingly.
And then your pre-processors wipe away that effort anyway…
Actually i m using image instead of multiple border now thx for this post it really very helpfull for me i m going to use these tips.
To get double borders, the “outline” property is great for boxy divs or page containers. You can also add rounded corners to outline to match the corners of your element border, like this:
You can also try these outline-style properties:
thanks for all your tips, Chris.
I just look at the demo and the effect is really cool. Kinda like photo frame thingy… Thanks for posting this tips. I can use this to create nice border for my image portfolio. :D
Personally, the box-shadow was worked for me. Completely forgot it existed but managed to use it to create metallic strips on the lefts and right of a box. Looked great, thanks to this guide :)
Thanks a lot. I was just using something like this except it didn’t had the z-index: -1; and therefore could not select anything in that div.
The z-index: -1; rule will cause the extra borders to hide underneath any parent elements with a normal z-index and a non-transparent background. To fix this, create z-index rules for each non-transparent parent element. You also need to add a non-static position, such as position:relative, to each one. HAX!
i not task compilit css multiple borders
Thanks alot, what a neat trick. But Is there any other css shorthand that can be used to assign border to all 4 sides instead of having to use border-left, border-top, etc?
Id just use an extra div or whatever block element. Cross browser supported, less time..
For those interested in more options, I have a post that lists 5 ways, with demos, to do multiple borders:
http://www.impressivewebs.com/multiple-borders-css/
Really valuable tool and almost what I needed – Is there a way to create the same effect but on one border only? i.e. I’m looking to create a line separator at the bottom of each block of text that has a solid 4px line, a gap of 3px and then a thinner 2px line WITHOUT creating another div container
Yes, multiple box shadows, and bottom margin. box shadows can be no blur and offset straight down.
now if you have rounded corners or want less than full width borders, you may need a different approach – pseudo elements and clever positioning will likely get you there
I sometimes :before and :after if I don’t want the line to encompass the whole element. The box-shadow method is pretty solid too :) Thanks!
there is also -moz-border-{top,right,bottom,left}-colors voir sur le MDN
but it is FF only…
Wow background-clip was exactly what I needed, but I never would have known it existed! Thanks, Chris!
Thanks for the demo , getting multiple border with some padding
.borders {
border: 5px solid blue;
outline: 5px solid red;
outline-offset :20px;
}
Instead of
z-index: -1;
in the pseudo element example, you can usepointer-events: none;
. Then you don’t have to worry about having a background color on the parent element, as well as any other unintendedz-index
weirdness.Thanks! You saved my night (I used solution: #Using box-shadow)!
Outline – of course!
box-shadow beats outline with border-radius support
I would just create a div in-between the 2 elements and add a border-top and a border-bottom.
Depends on the use case of course.