Treehouse: Grow your CSS skills. Land your dream job.

Last updated on:

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

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

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

    • Corry Frydlewicz
      Permalink to comment#

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

  7. 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. 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. 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. 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. 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. 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. waqar hussain
    Permalink to comment#

    i not task compilit css multiple borders

  14. 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. Juan
    Permalink to comment#

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

  16. 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. 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. 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. antoine9298
    Permalink to comment#

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

  20. Adam
    Permalink to comment#

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

Leave a Comment

Posting Code

We highly encourage you to post problematic HTML/CSS/JavaScript over on CodePen and include the link in your post. It's much easier to see, understand, and help with when you do that.

Markdown is supported, so you can write inline code like `<div>this</div>` or multiline blocks of code in in triple backtick fences like this:

```
<script>
  function example() {
    element.innerHTML = "<div>code</div>";
  }
</script>
```