June 4th, 2008 - by Paul OB

I’d like to share a couple of simple tips for adding graphical borders or side shadows to your CSS layouts. This article is mainly aimed at beginners but there are some useful tips for everyone if you’ll bear with the simpler stuff first.

CSS Full Length Graphical Borders on Fluid Layout

It’s quite easy to use graphical side borders on fixed width elements as you can simply repeat an appropriate sized image down the y-axis of the container and draw both edges at the same time. However, it is often not well understood how to achieve this effect with an element that has a fluid width especially in a 100% high environment.

We will first learn how to apply an image to both sides of a normal content height (but fluid width) container and then later on explore the possibilities of using this for a 100% (viewport high) container.

Normal Height Layout

Let’s start with a simple example that has graphical borders on both sides of a fluid layout.

The technique is to repeat the left border down the left side of the first wrapper and then repeat the right border down the right side of an inner wrapper. You must be careful not to overwrite the first image when you overlay the second image so any background colours would need to be on the first element and not the nested element.


  1. p {margin:0;padding-bottom:10px}
  2. #outer{border:1px solid #000;background: url(images/left-edge.gif) repeat-y left top;}
  3. #inner {margin-left:20px;background: url(images/right-edge.gif) repeat-y right top}
  4. #content{margin-right:20px;}
  5. /* mac hide - force layout in ie \*/
  6. * html #outer {height:1%}
  7. /* end hide */
  1. <div id="outer">
  2.     <div id="inner">
  3.         <div id="content">
  4.             <p>This is the content : this is the content : </p>
  5.             <p>This is the content : this is the content : </p>
  6.         </div>
  7.     </div>
  8. </div>

The side image is 20px wide so the elements are nested allowing for a 20px gap using margins to keep the content away from the borders. We could have done the same thing with padding and saved ourselves an extra div.

  1. p {margin:0;padding-bottom:10px}
  2. #outer{
  3.     border:1px solid #000;
  4.     background: url(images/left-edge.gif) repeat-y left top;
  5.     padding:0 0 0 20px;
  6. }
  7. #inner {
  8.     padding:0 20px 0 0;
  9.     background: url(images/right-edge.gif) repeat-y right top;
  10. }
  11. /* mac hide - force layout in ie \*/
  12. * html #outer,* html #inner {height:1%}
  13. /* end hide */
  1. <div id="outer">
  2.     <div id="inner">
  3.         <p>This is the content : this is the content : This is the content : this is the content : This is the content : this is the content : This is the content : this is the content : This is the content : this is the content : This is the content : this is the content : This is the content : this is
  4.             the content : This is the content : this is the content : This is the content : this is the content : This is the content : this is the content : This is the content : this is the content : </p>
  5.         <p>This is the content : this is the content : This is the content : this is the content : This is the content : this is the content : This is the content : this is the content : This is the content : this is the content : This is the content : this is the content : This is the content : this is
  6.             the content : This is the content : this is the content : This is the content : this is the content : This is the content : this is the content : This is the content : this is the content : </p>
  8.         <p>This is the content : this is the content : </p>
  9.         <p>This is the content : this is the content : </p>
  10.     </div>
  11. </div>

The only thing to note in both the above snippets is the “haslayout” fix for IE. If you are not familiar with “haslayout” then I have a good explanation here.

Figure 1 shows the result of the above code.

Figure 1

If you have a little imagination you can improve the look — here is another example as shown in Figure 2.

Figure 2

All that was needed was to change the image slightly and give the background a colour that merges in with the image.

  1. .outer{
  2.     width:50%;
  3.     background:#ffe6a5 url(images/ragged-left2.gif) repeat-y left top;
  4. }

The simple change above gives the layout a nice torn look down each side.

100% Height Borders

So far we have established that it is easy to place a repeating graphic on each side of a normal height layout, but what about 100% high layouts where the layout stretches from the top of the viewport to the bottom of the viewport?

This is more complicated because 100% height is a tricky subject at the best of times. In effect you can only ever have one 100% high element to play with and therefore with a fluid width element you can’t tile both edges of the element in one go with a background image.

100% Height Explained

I suppose I should explain why you cannot have more than one 100% high element!

In order to achieve an initial 100% high container the html and body elements are first set to 100% height. This allows us to use the main-container on the page and to give it min-height:100%. We use min-height because we want a minimum of 100% height but we also want the height to expand should content exceed the viewport height. If we had used height:100% for the main container then the container would never expand past the viewport and content would just spill out. Therefore we use min-height:100% to get our initial 100% height.

However, because we must use min-height on the main container we cannot nest another element inside that container and use min-height again.

Why Not?

The reason is that a percentage height of an element must be based on the parent’s height. If the parent is defined as height:auto (the default) then the child has no height to base its measurements on and the height collapses to auto (for both height and min-height) which is effectively content height. This is an impossible conundrum and the reason is that in most cases you can only ever work with one 100% high container and that must be the first container on the page.

I should point out that IE6 and under do not understand min-height but treat height as a minimum anyway so that is the reason you will see the IE hacks for this. In some cases IE6 will allow you to nest successive 100% high elements but other browsers will not so it’s best avoided.

Now with the 100% height issue explained we can set about creating our 100% high borders. Let’s start with the basic page.

  1. * {margin:0;padding:0}/* for demo only use a proper reset in real life */
  2. p,h1{margin:0 0 1em 0}
  3. html,body{height:100%}
  4. body {
  5.     font:13px arial,helvetica,sans-serif;
  6.     background:#ccc;
  7.     color:#000;
  8. }
  9. #wrapper{
  10.     position:relative;
  11.     margin:0 6%;
  12.     min-height:100%;
  13.     background:#6b97c8;
  14.     color:#fff;
  15.     padding:0 50px;
  16. }
  17. * html #wrapper{height:100%}/* for ie6 and under*/
  1. <div id="wrapper">
  2.     <h1>Full Length side border images</h1>
  3.     <p>This is the content : </p>
  4. </div>

Here is a live page using the above code. Simple stuff so far with the 100% height routine as mentioned earlier. Now we need a method of painting both edges with our repeating graphics. We can’t nest any inner elements because they will only be content height and will look bad.

Therefore we are going to use a technique I devised for making equal columns and will apply it to make our borders. You should read the article for the full details but briefly the idea goes like this…

An absolute element is placed using top and bottom properties at the same time to hold it in tune with the outer parent. The outer parent has position:relative applied and this keeps the inner absolute element relative to itself at all times. By specifying top and bottom properties at the same time the absolute element will keep its top and bottom in place with the top and bottom of the parent always creating a 100% high element.

Unfortunately IE6 and under don’t understand it when you use top and bottom together so instead for IE6 and under only we place the absolute element at the bottom of the element and give it a height that will be bigger than we ever need. It doesn’t matter that the height is too big because it will simply disappear through the top of the viewport without any ill-effects.

In fact, for other browsers we don’t need to use top and bottom properties at the same time. We can simply give the element a top position and then specify 100%:height. Unlike static elements, absolute elements will keep track of an auto height container.

Time for a demonstration.

The css we add to the snippet above is as follows.

  1. #edgeL{
  2.     position:absolute;
  3.     bottom:0;
  4.     left:0;
  5.     width: 34px;
  6.     height:100%;
  7.     background:url(images/left-graphic2.jpg) repeat-y 0 0;
  8.     border-right:1px solid #000;
  9. }
  10. #edgeR{
  11.     position:absolute;
  12.     bottom:0;
  13.     right:-1px;/* hide background jog in IE6*/
  14.     width: 34px;
  15.     height:100%;
  16.     background:url(images/right-graphic2.jpg) repeat-y 0 0;
  17.     border-left:1px solid #000;
  19. }
  21. * html #edgeR,
  22. * html #edgeL{height:1000em}/* for ie6- height bigger than page will ever be*/

The html is simple also:

  1. <div id="wrapper">
  2.     <h1>Full Length side border images</h1>
  3.     <p>This is the content</p>
  4.     <div id="edgeL"></div>
  5.     <div id="edgeR"></div>
  6. </div>

The two extra divs that we are utilizing for the borders are shoved to the bottom of the current stacking context and kept nicely out of the way. This method is so simple and the extra mark-up is minimal as only one extra div than the normal height method.

Adding Transparent Shadows

A lot of sites like to have their main page bordered down the side with a transparent shadow effect. In order to do this properly transparent pngs need to be used so that the body background isn’t rubbed out and can still be seen below the shadow. This is especially important if the body background has a gradient effect or has fixed images that need to be visible under the shadow.

Unfortunately IE6 (and older) don’t understand how to use transparent pngs and you loseWeight Exercise any opacity with horrible effect. Fortunately we can use the proprietary alpha image loader filter to provide IE6 and 5.5 with some sort of fix. As the filter is a Microsoft extension it’s best to feed it to only IE6/5.5 (preferably via Conditional comments). For ease I have used the star selector hack to target IE6 and 5.5. I am ignoring IE5.0 as it doesn’t understand the filter but you may wish to supply alternative non-transparent images to IE5 only using conditional comments.

For all other browsers we can simply use the code as shown above and instead of the border images we will use transparent pngs for the borders. For IE5.5/6 we need to add the filter which will make the relevant code look like this.

  1. #edgeL{
  2.     position:absolute;
  3.     bottom:0;
  4.     left:0;
  5.     width: 34px;
  6.     height:100%;
  7.     background:url(images/left-border.png) repeat-y 0 0;
  8. }
  9. * html #edgeL {
  10.     background:none;
  11.     filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/left-border.png',sizingMethod='scale');
  12. }
  13. #edgeR{
  14.     position:absolute;
  15.     bottom:0;
  16.     right:-1px;/* hide background jog in IE6*/
  17.     width: 34px;
  18.     height:100%;
  19.     background:url(images/right-border.png) repeat-y 0 0;
  20.     border-left:1px solid #000;
  21. }
  22. * html #edgeR {
  23.     background:none;
  24.     filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/right-border.png',sizingMethod='scale');
  25. }

The image gets supplied to IE6 using the star selector hack but an important point to note is that you must remove the original image because it would conflict with the filter image and ruin the effect. That is the reason for the “background:none” in the IE hack.

Note also that the sizingMethod attribute is set to scale so that the image is scaled to the full height of the element it sits in. This filter is not a substitute for the background property and has limited capabilities. Read more about it in the Ultimate CSS Reference.

Here is a live example with the changes recommended (view source for the full code).

Figure 3

If you want the main wrapper to have a background colour then you need to move the edges outside of the wrapper so that the transparency isn’t affected. This can easily be done by adjusting the left and right positions of the absolute elements.

Here is another live example with the background color added and the edges moved outside the main background (view source for the full code).

Figure 4

That about wraps it up for today and I’m sure you can come up with some better examples than me. Hope you find it useful.

Be Sociable, Share!

11 Responses to “CSS – Bordering on The Ridiculous”

1 jitendra

very good article, i wanted to know about this trick , thanks man

2 Crusher

Thank you for you share, i’ll come back to visit this site.

3 Golgotha

I could have really used this article back in the day Paul, so I’m sure someone, somewhere is really loving this article right about now.

4 Paul OB

Glad you liked it :)

5 JeffersonHI

Lucid explanations, excellent examples – this was EXACTLY what I needed. Thanks, Paul!

6 Patrick Burt

Looks good, but why do you need the height 1%?

7 Paul OB

Hi Patricj=k,

The height:1% in the first examples was to force “haslayout” in IE as I mentioned in the article. :)

If the element doesn’t have “haslayout” then things will soon start to go wrong and become mis-positioned.


The later examples are using the height:100% routines and therefore don’t need the 1% hack.

8 Advocatus D.

Very informative! Found this post from a PoshCSS posting.

Great explanation of using 100% dimensions. You definitely cleared up some confusion I’ve had. I imagine I’ll be using this knowledge in the future. Thanks!

9 links for 2008-06-14 « Richard@Home

[...] CSS – Bordering on The Ridiculous Nice tutorial covering how to add left and right borders to an element. Markup is pretty clean, but the CSS has some hacks for IE that I would rather see in an IE only stylesheet. (tags: css borders tutorial) [...]

10 Fix Your CSS

[...] We can’t really use this method for our fixed footer because it serves no purpose if we can’t see it. A change of tact is needed and we will need to fix the footer to the bottom of the viewport using the bottom property while not specifying left or right positions so that our element holds true to the centered layout. However we will also need to use a 100% high centered layout if we want borders to meet the footer, otherwise it may look a bit detached. (Read my explanation on 100% height in the middle paragraphs here.) [...]

11 hakan

good thanks

Share your thoughts...

mulberry sale spyder womens jacket cheap new balance 574 mulberry outlet cheap new balance 574 arcteryx outlet mulberry sale spyder womens jacket mulberry sale spyder womens jacket mulberry outlet mulberry outlet new balance 574

Popular Articles

Top 10 Commentators

Subscribe to this feed! Subscribe by Email!

Random Bits Podcast

You need to download the Flash player from Adobe

Blogs Worth Reading