Quick Tip: Multiple Borders with Simple CSS
videos

Quick Tip: Multiple Borders with Simple CSS

Tutorial Details
  • Topic: CSS Borders
  • Difficulty: Intermediate
  • Completion Time: 5 Minutes

Did you know that we can achieve multiple borders with simple CSS, by using the :after amd :before psuedo-classes? This is something I recently learned myself! I’ll show you how to add more depth to your designs, without images, in just a few minutes.


Final Code

<!DOCTYPE html>

<html lang="en">
<head>
	<meta charset="utf-8">
	<title>Multi-Borders</title>
	<style>
		body { background: #d2d1d0; }
		
		#box {
			background: #f4f4f4;
			border: 1px solid #bbbbbb;
			width: 200px;
			height: 200px;
			margin: 60px auto;
			position: relative;
		}
		
		#box:before {
			border: 1px solid white;
			content: '';
			width: 198px;
			height: 198px;
			position: absolute;
		}
		
		#box:after {
			content: '';
			position: absolute;
			width: 196px;
			height: 196px;
			border: 1px solid #bbbbbb;
			left: 1px; top: 1px;
		}
	</style>

</head>
<body>
	<div id="box"></div>
</body>
</html>

In short, any browser that supports the :before and :after psuedo-elements (all major browsers) can take advantage of this effect. Of course, there are alternatives, including the use of box-shadow, as well as adding additional mark-up to the page; however, this is clean solution that you should definitely consider. Thanks for watching!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.johnwooten.info drumkeyjw

    Thanks so much! I really enjoy these quick tips…

  • http://www.friendevent.me Jon

    Jeffrey,

    I just wanted to thank you for the jQuery series you did. I just finished it this morning and it helped me tremendously.

    I Just wanted to let you know that your work is appreciated. I’m getting ready to tackle the PHP series now and watch the above quick tip as well.

    thx again.

  • http://www.jeffrey-way.com Jeffrey Way
    Author

    Hey guys — I actually discovered this technique from a blog a week ago or so…but I can’t remember where. If anyone knows, reply to this comment, and I’ll be sure to link to the blog I learned it from. :)

    • ArnaudB

      Here is the original article, by Nicolas Gallagher :
      http://nicolasgallagher.com/multiple-backgrounds-and-borders-with-css2/

      Nice to have a video Quick Tip about it ! Thanks !

    • Teddy

      Heh, I was just about to give a rant about you not giving credit to Nicolas for this tip – since it was obvious you learnt it from his blog last week ;) I’d love to see some attribution in the blog post itself. Keep the quick tips coming. It’s great to see such a high quality web development site out here for all the new people trying to learn.

    • http://www.flickr.com/armin_san Armin

      According to quircksmode, :before and :after aren’t supported by IE, except IE8:
      http://www.quirksmode.org/css/contents.html#t15

    • Thomas McDonald

      I discovered this from Freshface’s tooltips :)

  • http://daniel-groves.co.uk Daniel Groves

    Nice idea, I like it.

    Although, the final result you their in the video could have been achieved with “border: 1px double #bbb”

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Of course. But you could change it up however you wanted. This provides a bit more control over the colors, styling, spacing, etc.

  • http://www.virtualerik.com Erik

    That’s an awesome tip, thanks for sharing!

    How do you get that live preview next to Coda?

  • Mohamed Zahran

    Hi Jeff, I would like to see a PHP tutorial written by your own. By the way, your css quick tips works properly and it helps us a lot but we’re greedy to learn from your experiences!

    Yours, Mohammed

  • http://www.limefox.co.uk Kent Website Designer

    This is interesting – i’m not sure I would use the example given but this is my first discovery of the content: property.

    As always, thanks for your wisdom, i’m off to do more research!

  • http://emmediagroup.com Ted

    Much quicker and cleaner than the way I was doing it before! Thanks

  • http://www.sayhelloharmony.com Brian Kulp

    Nice effect! Thanks Jeffrey.
    I will be using this in my current project to get that nice depth effect.

  • http://www.nouveller.com/ Benjamin Reid

    I’ve actually strayed away from using this ‘highlighting’ technique when designing as I didn’t want to add extra markup but once again, problem solved!

    Thank-you muchly!

  • http://filmsamlare.se/ Thim

    WOW! Thnx Jeffrey!

    This quick tip helped alot, thnx for sharing :)

  • http://briancampbell.name Brian

    Seems this only works with a fixed height/width value? You could make some killer buttons with this technique and CSS3 background gradients…if it would allow for variable widths :P

    • Teddy

      Why wouldn’t it work with dynamic dimensions? I’m using it on a new design I’m working on and it works just fine.

      • http://briancampbell.name Brian

        Really? Mind sharing your code? It’s definitely not working for me. Once i take the height/width parameters out of the css it falls apart (in Safari anyway)

    • http://www.kreatech.net Ejaz

      Nice tip Jeff, is there any solution for variable height/width?

      • http://www.nouveller.com/ Benjamin Reid

        If you haven’t declared width and height, try “width: auto; height: auto”.

      • Daniel

        if you set both top, right, bottom, and left to 1px, and delete the width and height declarations it works wonderful with variable height/width!

        thanks jeff!!

  • JohnDel

    Nice trick but it doesn’t work in internet explorer 7 and later. It works in ie 8.

  • http://www.kopflos.eu Thomas

    Thanks for this tutorial.

    Where did you get this TextMate like color scheme?

    Thanks
    Thomas

  • Karl

    i have just tried this technique for a box that contains a hyperlink and now the link does seem to be clickable… any ideas?

    • Gautam Chadha

      It is because :after pseudo class adds another layer in front of the box class. To over come this problem you can change the z-index property on the pseudo classes so that they are positioned behind the original class.

      Multi-Borders

      body { background: #d2d1d0; }

      #box {
      background: #f4f4f4;
      border: 1px solid #bbbbbb;
      width: 196px;
      height: 196px;
      margin: 60px auto;
      position: relative;
      z-index:50;
      }

      #box:before {
      border: 1px solid white;
      content: ”;
      width: 198px;
      height: 198px;
      position: absolute;
      z-index:-2000;
      left:-2px; top:-2px
      }

      #box:after {
      content: ”;
      position: absolute;
      width: 200px;
      height: 200px;
      border: 1px solid #bbbbbb;
      left: -3px; top: -3px;
      z-index:-500;
      }

      Google.com

      • Pepitoto

        Thx guy, I was looking for that solution for a couple of days

  • Christophor S.

    This was great! thanks Jeffrey

  • Gautam Chadha

    Nice tutorial Jeffrey. I was just playing with the code and found that further adding outline to each of the pseudo class and the element property will allow usage of 6 different borders with just a single element.

  • http://blog.creative-webdesign.info Andi

    The result looks very cool but unfortunately not all the browsers support this feature…

  • jmarreros

    Interesting tip, Thanks for sharing

  • http://dougneiner.com Doug Neiner

    I think it is fine that it doesn’t work in IE <7, but just wanted you to be aware it completely breaks in FF 3.0 since they have `:before` and `:after` *partially* implemented. They have it implemented enough to show the boxes, but not enough to fully position them.

    Apart from that, this is a great technique and has a *ton* of application in the mobile world where Webkit dominates!

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Ahh – that’s interesting; though, I’d imagine that the upgrade percentage from Firefox 3.0 is super high.

      Another possibility would be to use -moz-borders, but that’s of course Firefox-specific.

  • http://teslacreations.com Karol

    Great stuff.
    I think it’s worth adding that it even works with css3 rounded corners! You have to add -moz/webkit-border-radius to both pseudo-classes and the actual class, but the result is worth it :)

  • http://www.vectelligence.com Ilie Ciorba

    Very nice tip, going to give it a try

  • http://925html.com/ Eric Ferraiuolo

    You realize that your code creates an unusable situation if you have any content in the box, right? The :before and :after pseudo elements overlay the content blocking it from user interaction. Put a link in side your box and try to click it!

  • Djkanna

    I noticed that if you use something like border-radius on your box, you have to apply it to the after/before aswell. (most might know this but I thought I’d point it out aswell :) )

    Nice tip Jeffrey.

    • http://www.web.deverz.com Djkannad

      Aye whoops didn’t realise someone said it Two comments up my bad!

  • http://magplazza.com Mike

    Thanks! This is a great article :)

  • http://www.alfystudio.com Ahmad Alfy

    WOW that was new! Thanks, I really enjoyed that and definitely gonna use it :)

  • http://www.obdsvs.com vas 5054a

    Thank you first.But the last I coudn’t see.can you say it more clearly?

  • http://www.nb-nc.com Grinding machine

    Nice and useful tips as for me! Thanks for sharing! Yo seem to be a really professional!

  • http://www.kitfoxink.com Kit MacAllister

    Nice tip! I’m looking forward to using this.

  • http://www.xcellence-it.com Xcellence IT

    Great, thanks for this great technique.

  • http://spasquini.interfree.it Sauro

    I want only to tell that in general I hate video tutorials. Much better to follow a step-by-step instruction that you can also print down and follow off-line.
    But expecially in coding, video tutorials are really a creepy tool. They let you to loose a lot of time.

  • Diane

    Awesome tip, thx!

  • Robbert

    A great technique thank you for sharing! Keep up the good work.

  • http://nicolasgallagher.com Nicolas Gallagher

    Hi, my original article on multiple borders and backgrounds works with fluid-width containers because I used absolute positioning differently.

    If you want to emulate multiple background images in IE8 (and other effects) you can find out more here:

    http://nicolasgallagher.com/multiple-backgrounds-and-borders-with-css2/

  • Damion

    I have been trying to get a double top border, and ended up using outline and then i had to try to hide the sides and bottom. This was a big help.

    Thank you.

  • http://www.rittencommedia.dk Jimmy Rittenborg

    Thank you so much for this neat little quick tip Jeffrey.

    - that solves the problem of simulating that nice subtle image border effect like img {padding:2px; border:1px solid #ccc; background:white;} -on boxes :)

  • http://www.codecrunchers.net Kevin Groenendaal

    Jeffrey, you know you could zoom in far more with the CTRL + Scroll technique, right? Just in case.

    Neat trick, greatly explained!

    Kev

  • http://www.point269.com Dasha

    This is totally awesome! Thank you for sharing and explaining it very well. I was looking for this the other day – win! Thanks again.

  • http://www.andrewckor.com/ Andrew Ckor

    Nice Jeffry and what? when we have a resizable (height) box??

    • Haziq

      I think adding a display: block line would do. At least, it worked for me just a few hours ago.

  • http://www.sz-media.org Sz-Media.org

    This is such a nice post. typical nettuts quality! i am looking forward to the wordpress 3.0 feature tutorial :)

  • http://www.jordanwalker.net Jordan Walker

    Great implementation, that would be a great way to set off photographs.

  • http://www.crearedesign.co.uk Steve Maggs

    Wow, a lot of comments for what is essentially a simple post! It is a really useful and potentially wide ranging tip though, so thanks for coming up with it.

    Also love the HTML tags post, quick reads like this are always handy. Although it takes twice as long to wade through the comments!

  • Haziq

    Thanks for this cool tut! Jeffrey and Nicolas rock! I like the idea how Nicolas created Pure CSS Social Media Icons using :before and :after pseudo classes.

  • Mike

    A great post and a great technique – unlike Sauro I just love video tutorials!

    Jeffrey – if you really want to impress me, how do you work the same effect on a fieldset border? I have tried

    fieldset:before{}

    but it doesn’t repeat the break for the legend.

  • Laz

    Wonderful, thanks!

    I just used it to create a border that changes color… just by setting the :before border-bottom to none and the :before height to half of the box’s (repositioning it by -1px top and left). Works like a charm!

    #box {
    width: 100px;
    height: 100px;
    border: 1px solid #000;
    position: relative;
    }

    #box:before {
    border: 1px solid red;
    border-bottom: none;
    content: ”;
    width: 100px;
    height: 50px;
    top: -1px;
    left: -1px;
    position: absolute;
    }

  • http://www.u2u.ir Heam

    It helps a lot … thanks for sharing …

  • http://JonathanCutrell.com Jonathan Cutrell

    Great post, Jeffrey. I’m using this technique in a webkit specific app – works quite nicely, and plays well with content.

    Just wanted to point out to IE folks,

    If you really need a double border, it is important to solve the problem early. The best solution, imo, to keep your markup readable, is to use jQuery, and do something like this:

    $(‘.someClass’).wrap(“”);

    Then use CSS to style accordingly.

    Check out this nifty little example.
    http://jsfiddle.net/39uLf/

  • http://JonathanCutrell.com Jonathan Cutrell

    ^^ That .wrap(“”) is supposed to have a div class=”anotherClass” in it. :)

  • http://jonyarbor.name Jonathan Yarbor

    Rather than deal with the width of the parent on the :before and :after you can set their position absolutely rather than the width. This allows for dynamic sized without having to rewrite this code over and over again.

    #box:before{
    border: 1px solid #ffcc99;
    content: ”;
    position: absolute;
    top:0;
    bottom:0;
    left:0;
    right:0;
    }
    #box:after{
    border: 1px solid #ffcc99;
    content: ”;
    position: absolute;
    top:1px;
    bottom:1px;
    left:1px;
    right:1px;
    }

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Good point.

    • http://nicolasgallagher.com Nicolas Gallagher

      This is the method I use in the original article. But you also need to set some z-index values to avoid the pseudo-elements sitting on top of your content rendering it unselectable and links unclickable. Unfortunately, this nettuts article misses out the bits of CSS that are required to make this more flexible and practical.

  • Jasper

    Can’t dis be done with ‘border: 3px double #BBBBBB;’? Or did I missed something?