Multiple Borders

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.

Comments

  1. User Avatar
    Brad
    Permalink to comment#

    So glad you have things here that should be obvious but elude the brain during the days work. Thanks Chris – appreciated

  2. User Avatar
    Dietmar
    Permalink to comment#

    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?

  3. User Avatar
    Dave
    Permalink to comment#

    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.

  4. User Avatar
    Frank
    Permalink to comment#

    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

    #borders {
       position:relative;
       background:#B2C1C8;
       margin:10px
    
    }
    
    #borders:before {
       content: " ";
       position: absolute;
       z-index: -1;
       top: -10px;
       left: -10px;
       right: -10px;
       bottom: -10px;
       border: 1px solid #B2C1C8
    }
    
  5. User Avatar
    Jeff Feely
    Permalink to comment#

    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!

    .bevel{
    box-shadow: 
    0px 8px 5px -5px RGBA(0,0,0,.6),
    inset 3px 3px 5px 0px RGBA(0,0,0,.1), 
    inset -3px -3px 5px 0px RGBA(255,255,255,.4);
    }
    
  6. User Avatar
    Saeed Neamati
    Permalink to comment#

    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

    
    .some-class
    {
             box-shadow: 0 0 3px black;
    }
    

    I think he expects to see a shadow (or a glow) in your site, not a solid, border-like outline.

    • User Avatar
      CpILL
      Permalink to comment#

      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”.

    • User Avatar
      Tobi Vogler
      Permalink to comment#

      Well, the example you gave is in fact a shadow or glow, not solid outline.

      I guess you meant

      box-shadow: 0 0 0 3px black
      

      which gives a solid, 3 pixel outline.

      And if a user understands CSS, he will know this and expect accordingly.

    • User Avatar
      Corry Frydlewicz
      Permalink to comment#

      And then your pre-processors wipe away that effort anyway…

  7. User Avatar
    ashish
    Permalink to comment#

    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.

  8. User Avatar
    Rowe Morehouse
    Permalink to comment#

    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:

    .container {
    border: 1px solid #999;
    outline: 1px solid #eee;
    border-radius: 3px; -webkit-border-radius: 3px; -moz-border-radius: 3px;
    outline-radius: 3px; -webkit-outline-radius: 3px; -moz-outline-radius: 3px; }
    

    You can also try these outline-style properties:

    outline-style: dotted;
    
    dashed
    double
    groove
    ridge
    inset
    outset
    

    thanks for all your tips, Chris.

  9. User Avatar
    Syamsul Alam
    Permalink to comment#

    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

  10. User Avatar
    Matt
    Permalink to comment#

    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 :)

  11. User Avatar
    Christophe Debruel
    Permalink to comment#

    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.

  12. User Avatar
    Wes
    Permalink to comment#

    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!

  13. User Avatar
    waqar hussain
    Permalink to comment#

    i not task compilit css multiple borders

  14. User Avatar
    Hyip
    Permalink to comment#

    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?

  15. User Avatar
    Juan
    Permalink to comment#

    Id just use an extra div or whatever block element. Cross browser supported, less time..

  16. User Avatar
    Louis
    Permalink to comment#

    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/

  17. User Avatar
    Shannon Whitty
    Permalink to comment#

    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

  18. User Avatar
    Corry Frydlewicz
    Permalink to comment#

    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!

  19. User Avatar
    antoine9298
    Permalink to comment#

    there is also -moz-border-{top,right,bottom,left}-colors voir sur le MDN
    but it is FF only…

  20. User Avatar
    Adam
    Permalink to comment#

    Wow background-clip was exactly what I needed, but I never would have known it existed! Thanks, Chris!

  21. User Avatar
    ramey29
    Permalink to comment#

    Thanks for the demo , getting multiple border with some padding
    .borders {
    border: 5px solid blue;
    outline: 5px solid red;
    outline-offset :20px;
    }

Submit a Comment

Posting Code

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.

icon-closeicon-emailicon-linkicon-logo-staricon-menuicon-searchicon-staricon-tag