Faux Columns

A note from the editors: While excellent for its time, this article may not reflect modern best practices.

One of the questions I get asked the most often regarding my personal site’s design is the following:

Article Continues Below

How do you get the right column’s background color to extend all the way down the page?

It’s a simple concept, really — one that many of you may already be familiar with.  But for those who aren’t, the following technique can be a handy little trick.

Vertical stretch#section2

One of the somewhat frustrating properties of CSS is the fact that elements only stretch vertically as far as they need to.  Meaning, if a 200-pixel tall image is contained within a <div>, the <div> will only expand down the page 200 pixels.

This becomes an interesting dilemma when you use <div>s to section your markup, then apply CSS to create a columnar layout.  One column may be longer than the other (see Figure 1). Depending on the amount of content contained, it becomes difficult to create a layout with two equally tall columns when a unique background color is desired for each column.

figure 1
Figure 1

There are a few ways to make the columns appear equal in length, regardless of the content that they contain.  I’m sharing my particular solution (for use with an absolutely positioned layout), which happens to be pretty darned … simple.  This same little trick is also used elsewhere, including this very site.

The cheat#section3

The embarrassingly simple secret is to use a vertically tiled background image to create the illusion of colored columns. For SimpleBits, my background image looks something like Figure 2 (proportions changed for demonstration), with a decorative stripy thing on the left, a wide white section for the content column, a 1 pixel border, and a light brown section for the right column’s background followed by the reverse of the left side’s decorative border.

figure 2: background image for vertical tiling
Figure 2

The whole image is no more than a few pixels tall, but when vertically tiled, it creates the colored columns that will flow all the way down to the bottom of the page — regardless of the length of content in the columns.

The CSS#section4

This elementary CSS rule is added to the body element:

background: #ccc url(../images/bg_birch_800.gif) repeat-y 50% 0;

Essentially, we’re making the entire page’s background color grey and tiling it vertically only (repeat-y).  The 50% 0 bit refers to the positioning of the background image — in this case, 50% from the left side of the browser window (resulting in a centered image) and 0 pixels from the top.

Positioned columns#section5

With the background image in place, my positioned layout sits on top, with padding and margins set for the left and right columns, ensuring that they will line up in the right place — within the faux columns created by the background image (see Figure 3).

figure 3
Figure 3>

It’s important to note that if borders, padding and margins are desired on either column, then we must still make up for IE/Win’s botching of the box model with Tantek Çelik’s Box Model Hack or Mid Pass Filter.

Alternatively, if borders or padding can be avoided altogether by just using margins instead, then the the Box Model Hack will not be necessary.  And if the column’s content is simply sitting (transparently) on top of the tiled background, then it should be easy to avoid the hack.

Whatever floats your boat#section6

While I use absolute positioning to create a two-column layout on my own site, equally fine results can be achieved via the float property (as seen here at ALA).

The same idea applies: tile the background image, then float a column in position to overlay the faux-column backdrop behind.

End notes#section7

It’s a simple concept, but one that may alleviate one of the frustrations that designers frequently encounter when building CSS-based layouts.

(Thanks to Jeffrey Zeldman for help in refining this article.)

About the Author

Dan Cederholm

Dan Cederholm is a designer, author, and speaker living in Salem, Massachusetts. He’s the Co-Founder of Dribbble, a community for designers, and Founder of SimpleBits, a tiny design studio. A long-time advocate of standards-based web design, Dan has worked with YouTube, Microsoft, Google, MTV, ESPN and others. He’s written several popular books about web design, and received a TechFellow award in early 2012. He’s currently an aspiring clawhammer banjoist and occasionally wears a baseball cap.

83 Reader Comments

  1. When I was tearing my hair out trying to get my blog to centre and stretch, I came across this method used by some guy over at css garden.

    But I didn’t know how to make it fluid and ended up using the “clear” method instead. But this is much simpler. Thanks!

  2. I’m designing a page where I have a footer image that finishes off the page nicely that I would like displayed at the aboslute bottom of the page every time. So naturally I just use that footer image as the body background with a specification of “no-repeat bottom center”.

    However, I have a 2-column content area that I want to stretch all the way down the page to meet the footer image regardless of the amount of content, but I’m already using that footer image as my body background, and obviously I don’t want that image tiled. Everything else I’ve tried seems dependant on the amount of content the div has.

    Is my only option to make an extremely tall background image (i.e. 4000+ px)?

  3. with this doctype:

    I was able to get a div to span(height) as far as I wanted to.

    If you specify a size in EM, and the content is larger than the given area in IE, the area will increase to fit the content…

    If you specify a size in %, and the content is larger than the given area in Moz, the area will increase to fit the content…

    so use the IE hack, to show IE ems, and Moz %s

  4. I tried this when I was redoing my site, but the whole thing fell apart when I tried put an image in the larger of the two divs. From what I’ve read, this appears to be a bug in the way the CSS is rendered. I’d love to be told I’m wrong about this – would your method work if you wanted to put an image in the top of the left column below the menu bar in this layout?

  5. On my site, I have fixed with columns (one on each side of the screen) and the middle column varies depending on how much space is left.

    What would I have to do to get it to work? You can check out my site (in IE, that’s where the problem is) at http://www.tim-weston.com/books/

  6. After first reading this I made an attempt at doing two columns with background colors that carry the full height.

    http://webhost.bridgew.edu/etribou/layouts/2col_colors_01/

    A little messy, but the idea is to create a fixed background block the width and height of the window and create a sort of color mask within that fixed background. Then place your content over it. This is done with z-indexing and fixed positioning. For IE, I use the fixed-positioning hack discussed at http://devnull.tagsoup.com/fixed/ .

    Haven’t tested it on Mac platform yet.

    Full-width footer doesn’t really work on this layout unless the content is taller than the user’s screen.

  7. With my site I am trying to “center” things at 25%. I am having quite a bit of fun trying to do this too. I have the same problem as others as my global div seems to be off a pixel on even window sizes. Am I just shooting myself in the foot trying to make this work? Making things even helped a lot but it is still not perfect.

  8. Can someone take a look at my layout for http://www.poker-resource.com? I have am using the faux columns trick, but right now the site is fixed with and I want it to be elastic. Trouble is I can wrap my head around how its possible to make liquid faux column layouts.

    If you can figure out how to do it with my site, please email me at wdami@stevens.edu with xhtml/css code if possible. Thanks alot!

  9. Ok, great idea, very cool. So, now as a CSS newbie in this realm of CSS, how do I put my 2-columns of text onto the page? I’m using a 700px wide background with a 500 px left, and a 200px right.

    I don’t know what clear, float, etc. etc. means (yet),and it would be nice to have a followup article (or maybe someone here can give me an example) on how to do this, for those of us that learn by doing rather than reading.

    Thanks!

  10. Here’s the xhtml:

    …content stuff

    And then, the CSS

    #wrapper {
    background: url(yourbgimage.gif) transparent repeat-y;
    width: 700px;
    }

    #menu {
    float: right;
    width: 190px;
    }

    #content {
    margin-right: 200px;
    }

    That’s very basic, but you should get the idea. 🙂

    Good luck.

  11. I’ll give it a whirl. I went ahead and created a table 700 px wide, centered, with one column at 500px and the oterh at 200px. It work’d. But that’s old school and I want to learn something new.

  12. It didn’t work. My #menu, which I called #left (for my sake) is centered. Isn’t the #right supposed to be marked absolute?

    I feel pretty grim at the moment that I can visualize this…

  13. I’m a dope. I think it actually worked. Will play with it further. I had #right labeled instead of #menu as in your example.

    Thanks!

  14. So, now when I add content to the #content div, the #menu top lines up with the #content bottom, in other words, it’s getting pushed down by the #content.

  15. I done this trick about 1 year ago when I made my personal website Dance Devils. I never thought it would end up as an article here though or I would have written the article.

  16. Does this only work in the body tag? I cannot get it to work in a div to save my life. Is there something special I need to do?

  17. This sounds similar to a problem I’m having on my site. Visit this page:

    http://www.rpgnext.com/tutorials.php

    The left and right columns are fixed and the center one is fluid. When you scroll down, you’ll notice that the background colors on the fixed columns ceases while the content continues. The css is available here:

    http://www.rpgnext.com/main.css

    Notice that both the #leftside and #rightside divs have “height: 100% ;”. I’m guessing that the 100% only referes to the initial browser window size. How can I get these to expand with the content ?

  18. You CAN in fact just specify ‘height: 100%;’ for just about anything, you just have to make the containing element have a height of 100% also.

    Try the following:

    html {height: 100%;}
    body {height: 100%;}
    #whatever {height: 100%;}

    Most people don’t seem to know about the ‘html’.

  19. I was just about to point out that height: 100% is depreciated and no longer works.

    I tested it, by creating a div:
    #tallbox{height: 100%;background-color: #000; width:40px;}

    it was invisible.
    so i added html,body{height:100%} to the style sheet, and it looked like it was working. I had a black 40px wide line going down the browser window.

    But when i filled the div with content that extended further than the initial window size, i found that the div did not continue. It was 100% of the initial view-point, not 100% as in all-the-way-to-the-bottom. In firefox (:. netscape also) that is, and Opera.

    IE displays it as expected, all the way to the bottom, no matter how much lipsum you throw into the div. This annoys me – the browser that usualy throws up several hurdles a day finaly does something as expected…

  20. I don’t know about anyone else, but this article by Dan has really ‘saved the day’ for me. I was redesigning my own site and I desperately wanted to know how I could create this ‘effect’.

    I guess I had to wait no more. Dan’s article came just in time for me to put into practice what he wrote. I created a very simple background image and that did the trick.

    So far, I only had problems with Opera 6.0 for the Mac, but other than that, all of the mainstream browsers like IE 5.x, IE 6.0 for the Mac and for the Windows platform, Safari and all Gecko-based browsers do display it properly.

    Good job Dan!

  21. I’m sorry to say, but if your going to put any effort into making a tutotial, then at the bit which people will actually care about (Where you say about positioning the layers on top of the background) I don’t know if you could be any less clear. You just blab about, oh using margins and padding, here’s someone else’s useless tutorial about how do do this, and I’m not even going to tell you what part of the tutorial to look at. I suggest you be a bit more clear, because it the moment it’s useless, and very annoying, please redo it.

  22. I am in the process of going table-less, but curretnly it’s too much of a hurdle, so I’m going from inside out. Turning as many nested tables at a time into DIVs before I mess with the big one.

    I’ve got a repeating element going down the right side of the page. It’s a two column element with a 65px square image to the left and to the right, a title and a description followed by a link. you can check it out at calabashmusic.com (it’s a little f*d up at the moment thanks to my obsession with CSS).

    I want it to just not wrap around the image, so that it looks like:

    ———————-

    —— Title
    |IMG | textexttext
    | | text text
    —— tesxt text
    text text
    text text
    LINK

    unfortunately, the amount of text is dynamic, so if I set the image div to a fixed height, it will work, most of the time. Unless there is not much text. Otherwise it wraps around the image. Here is my code:

    #rightListItem {

    }
    #rightListItem .imgLayer{
    margin-left:4px;
    margin-right:8px;
    margin-bottom:25px;
    voice-family: “”}””;
    voice-family:inherit;
    width:63px;
    background: url(“/img/1pix.gif”) repeat-y: 50% 0;
    float:left;

    ————


    }
    #rightListItem {
    }
    #rightListItem .imgLayer img{
    height:63px; width:63px;
    }

  23. I am in the process of going table-less, but curretnly it’s too much of a hurdle, so I’m going from inside out. Turning as many nested tables at a time into DIVs before I mess with the big one.

    I’ve got a repeating element going down the right side of the page. It’s a two column element with a 65px square image to the left and to the right, a title and a description followed by a link. you can check it out at calabashmusic.com (it’s a little f*d up at the moment thanks to my obsession with CSS).

    I want it to just not wrap around the image, so that it looks like:

    ———————-

    —— Title
    |IMG | textexttext
    | | text text
    —— tesxt text
    text text
    text text
    LINK

    unfortunately, the amount of text is dynamic, so if I set the image div to a fixed height, it will work, most of the time. Unless there is not much text. Otherwise it wraps around the image. Here is my code:

    #rightListItem {

    }
    #rightListItem .imgLayer{
    margin-left:4px;
    margin-right:8px;
    margin-bottom:25px;
    voice-family: “”}””;
    voice-family:inherit;
    width:63px;
    background: url(“/img/1pix.gif”) repeat-y: 50% 0;
    float:left;

    ————


    }
    #rightListItem {
    }
    #rightListItem .imgLayer img{
    height:63px; width:63px;
    }

  24. I am in the process of going table-less, but curretnly it’s too much of a hurdle, so I’m going from inside out. Turning as many nested tables at a time into DIVs before I mess with the big one.

    I’ve got a repeating element going down the right side of the page. It’s a two column element with a 65px square image to the left and to the right, a title and a description followed by a link. you can check it out at calabashmusic.com (it’s a little f*d up at the moment thanks to my obsession with CSS).

    I want it to just not wrap around the image, so that it looks like:

    ———————-

    —— Title
    |IMG | textexttext
    | | text text
    —— tesxt text
    text text
    text text
    LINK

    unfortunately, the amount of text is dynamic, so if I set the image div to a fixed height, it will work, most of the time. Unless there is not much text. Otherwise it wraps around the image. Here is my code:

    #rightListItem {

    }
    #rightListItem .imgLayer{
    margin-left:4px;
    margin-right:8px;
    margin-bottom:25px;
    voice-family: “”}””;
    voice-family:inherit;
    width:63px;
    background: url(“/img/1pix.gif”) repeat-y: 50% 0;
    float:left;

    ————


    }
    #rightListItem {
    }
    #rightListItem .imgLayer img{
    height:63px; width:63px;
    }

  25. Don’t set a height for the right div.
    Use this (thanks to PPK):
    var y;
    var test1 = document.body.scrollHeight;
    var test2 = document.body.offsetHeight
    if (test1 > test2)
    {

    y = document.body.scrollHeight;
    }
    else
    {

    y = document.body.offsetHeight;
    }

    document.getElementById(“navbar”).style.height=y;
    This way you don’t need images. I don’t like images in a design.

  26. Hope I can get a quick pointer about centering. I’m still slow to adapt to layers, and have been stuck on this for a few days. The faux columns article is helpful, but doesn’t mention much about how to get the content to line up properly with the BG. I’m getting close, but it never matches up properly unless I start using huge negative values in the poistioning properties that causes some unpredicyable behaviour across browsers.

    Can someone point me to a tutorial or give me a basic run down of how this is done? I have a BG image that’s 780px and two colored columns with borders that goes over the top, sorta like simple bits.

    thanks.

Got something to say?

We have turned off comments, but you can see what folks had to say before we did so.

More from ALA

I am a creative.

A List Apart founder and web design OG Zeldman ponders the moments of inspiration, the hours of plodding, and the ultimate mystery at the heart of a creative career.
Career