Lining a background image up with the bottom of another column

Here is the situation: you have two columns, one contains your main content and the other is navigation or some sort of sidebar. You place a picture underneath your navigation and want to have it line up with the bottom of your main content. How do you do that? Read on to find out...but before I continue, thanks are in order to Bryan Wootan for coming up with the idea for this tutorial.

Why not percentages?

Surely the solution is simple - give both columns a percentage height relative to either a parent element or the body and html tags (which is what we do when we want to align something vertically to the viewport). But alas, this doesn't work because the columns are now restricted to being as tall as the viewport, and as soon as the main content becomes larger unsightly scrollbars appear.

Why not definite heights?

Definite heights for anything that contains a lot of text aren't a good idea. Text grows over time, which means lots of fiddly maintenance, and users browse your site with a multitude of different resolutions, which would make definite height columns look silly for some people. Given you want an all-round nice looking and properly functioning site, one of your goals should be to make sure it looks good under as many circumstances as possible. Anyway, I digress, let's see how to overcome this tricky problem.

The fix

To get our image to line up with the bottom of our main content, we need to perform some CSS background magic!

Example

In this example, we have our navigation, called nav on the left, and our main content, called main on the right. Both divs are inside a parent called container. We would like to place a picture of a Mini in the same column as out navigation, but line it up with the bottom of the text in main.

CSS Code:

        #container {
            background:#9CC url(../images/mini_200.jpg) no-repeat 0 100%; /* 0 100% is the same as left bottom */	
            width:900px;
            overflow:auto;
            margin:0 auto;	/* Added for example purposes */	  
            border: 1px solid #000; /* Added for example purposes */	  
        }
        
        #nav {
            list-style-type:none;
            display:block;
            width:200px;
            float:left;
            background-color:#F96; /* Added for example purposes */
            padding:0;
            margin:0;
        }
        
        #main {
            width:688px;
            float:left;
            background-color:#C96; /* Added for example purposes */
            padding:6px;
        }
        

(X)HTML Code:

        	<div id="container">
            	<div id="main">
                	... Your text...
                </div>
                <ul>
                	<li><a href="#" title="HTML">HTML</a></li>
                    <li><a href="#" title="XHTML">XHTML</a></li>
                    <li><a href="#" title="XML">XML</a></li>
                </ul>
         	</div>
        

Result

Click here for the result.

Explanation

Our image is added to the container as a background image. We then use CSS background positioning to position it to the left and bottom of container, by specifying two percentage values - the first for the horizontal position and the second the vertical position - 0 100%. This is identical to saying left bottom.

There's another important property that you will need to add to your container: overflow:auto. This tells the container to stretch to accommodate the two divs inside it. Without it, the container will act as if it has no content.

What if you want padding round the edge of your container?

If you want padding around the edge of your container, and still want your image to line up with the bottom of your text, you will have to use percentage values for your padding. The issue with this is that, say if you specify padding: 1% on container and then you deduct 1% from the horizontal and vertical background positions of your background image, so as the two match up, the result looks something like the following:

What...

The alignment is off kilter. Given percentage values are relative units of measurement and percentage background values align an image to the padding box of an element, I can only assume this is an issue to do with the background image not interpreting the boundary of the padding box the same as the content does. Either way, we can get round this by manipulating the margins on our nav and main instead.

Using margins

Before I go into the examples, please be aware that this method isn't bulletproof. There is still a slight discrepancy between the gap underneath the image and the gap underneath the content. The screenshot illustrates this in IE8. As you can see, it is fairly negligible, but if you strive for perfection, you may want to move onto the last solution which is adding a wrapper.

Thats no better...

Example of the "margin" method

CSS Code:

			
            #container {
                background:#9CC url(../images/mini.jpg) no-repeat 1% 99%; /* 0 100% is the same as left bottom */	
                width:900px;
                overflow:auto;
                margin:0 auto; /* Added for example purposes */	  		
                border: 1px solid #000;	/* Added for example purposes */	    	
            }
            
            #nav {
                list-style-type:none;
                display:block;
                width:200px;
                float:left;
                background-color:#F96; /* Added for example purposes */	  	
                margin:1% 0 1% 1%;
                padding:0;
            }
            
            
            #main {
                width:670px;
                padding:6px;
                float:left;
                background-color:#C96; /* Added for example purposes */	  
                margin:1% 1% 1% 0;		
            }
        

(X)HTML Code:

        	<div id="container">
            	<div id="main">
                	... Your text...
                </div>
                <ul>
                	<li><a href="#" title="HTML">HTML</a></li>
                    <li><a href="#" title="XHTML">XHTML</a></li>
                    <li><a href="#" title="XML">XML</a></li>
                </ul>
         	</div>
        

Result:

Click here for the result.

Explanation

This code looks complicated, but really isn't. To create small margins round the edge of our container, but make it look as if our two divs fit seamlessly together, we give our nav a top, bottom and left margin of 1%. We then give our main a top, right and bottom margin of 1%. This makes it appear as if there is an even padding around both divs. Next, we give our background image a position of 1% 99%, thus creating a 1% space to the left and below the image.

As you can see, this method isn't perfect. Even if you play around with half percentages or three-quarter percentages you're not going to see a seamless gap underneath both the background image and your content. If this is a problem for you, then the below method very well may save the day!

When you seek perfection...

If the above method doesn't cut it for you then you have one more option, which will ensure you have the same gap underneath the image as the content. It involves adding a wrapper div around our container and applying padding to that instead. And here is how it's done.

Example of the "wrapper" method

CSS Code:

          
            #container {
                padding:4px;	
                overflow:auto; /* Let our container know it has content */
                height:100%;
                width:900px;
                margin:0 auto; /* Added for example purposes */	  
                background-color:#9CC; /* Added for example purposes */	  
                border: 1px solid #000; /* Added for example purposes */	  	
            }
            
            #inner_container {
                background:url(../images/mini.jpg) no-repeat 0 100%; /* 0 100% is the same as left bottom */	
                width:900px;
                overflow:auto;                			  	
            }
            
            #nav {
                list-style-type:none;
                display:block;
                width:200px;
                float:left;
                background-color:#F96;	/* Added for example purposes */	   
                margin:0;
                padding:0;
            }
                        
            #main {
                width:686px;
                padding:6px;
                float:left;
                background-color:#C96; /* Added for example purposes */	  		
            }        
		

(X)HTML Code:

        <div id="container">
            <div id="inner_container">
                <div id="main">
                ... Your text...
                </div>
                <ul>
                	<li><a href="#" title="HTML">HTML</a></li>
                	<li><a href="#" title="XHTML">XHTML</a></li>
                	<li><a href="#" title="XML">XML</a></li>
                </ul>
            </div>
        </div>
        

Result:

Click here for the result.

Explanation

In this method, we may be adding an extra tag, but we're ensuring perfect alignment. If you have a design where the alignment absolutely must be spot on, this option is the best one for you; if perfect alignment isn't that important, then the margin method is for you.

Drop me a line

Got any questions? Get in touch via the contact form or email me @ helen@alternategateways.com.

Related Tutorials

Latest Tutorials

View all tutorials

Share/Save
Visit Alternate Gateways on Facebook