Grow your CSS skills. Land your dream job.

Last updated on:

Multiple Borders

Doing it with pseudo elements


Using pseudo elements for multiple borders
has fairly deep browser support as it's CSS 2.1 (not 3).

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.

#borders:before {
   content: " ";
   position: absolute;
   z-index: -1;
   top: 5px;
   left: 5px;
   right: 5px;
   bottom: 5px;
   border: 5px solid #ffea00;
}

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

Other Ways

Don't forget about the outline property. While it's a bit more limited than border (goes around entire element no matter what) it's an extra free border if that's what you need.

outline: 5px solid red;

If you are down with CSS3, you can use box-shadow (one of the deepest supported properties of CSS3) to get infinite (!) box shadows, by comma separating values.

box-shadow:
  0 0 0 10px hsl(0, 0%, 80%),
  0 0 0 15px hsl(0, 0%, 90%);

View Demo

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

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

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

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

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

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

Leave a Comment

Posting Code

Markdown is supported in the comment area, so you can write inline code in backticks like `this` or multiline blocks of code in in triple backtick fences like this:

```
<div>Example code</div>
```

It's broken though, and the Jetpack team is aware of it. Your best bet right now is to escape the code yourself and post in <pre><code> tags.

If formatting screws up, contact us and we can fix it up for you.

*May or may not contain any actual "CSS" or "Tricks".