Quick Tip: Mimic Equal Columns with CSS3 Gradients
videos

Quick Tip: Mimic Equal Columns with CSS3 Gradients

Tutorial Details
  • Topic: CSS3 Gradients, Equal Columns
  • Difficulty: Easy
This entry is part 4 of 16 in the CSS3 Mastery Session
« PreviousNext »

What happens when your main content area needs two specific background colors: one for the primary content, and another for the sidebar? If you’ve ever tried applying the background to each container itself, you’ll no doubt have realized that your layout quickly becomes fragmented as soon as, say, the primary content section exceeds the height of the sidebar.

Generally, the solution is to set a background image on the parent element, and set it to repeat vertically. However, if we get clever with CSS3 gradients, we can achieve the same effect with zero images. The irony in this is that we’re using CSS3 gradients to create an effect that doesn’t contain a gradient! Read on to learn more.


Prefer a Video Tutorial?


Step 1. Construction

Let’s begin by building a ridiculously simple layout. That way, we can demonstrate a common layout issue that we’ve all experienced at one point or another.

Create a new HTML document, and add the following to your body tag:

<body>

   <header>
      <h1> My Header </h1>
   </header>

   <div id="main">
      <div id="primary">Primary content.</div>
      <aside> 
         Sidebar
      </aside>
   </div>

</body>

Don’t forget that you can use the body element as a wrapper for your layout. Simply set a width directly to the body.

What we have here is fairly common. A header element contains a heading tag; and, then we have a main div, which houses the primary content, as well as the sidebar.


Step 2. Create the Columns

Next, let’s style this layout a bit. As we’re using the body element as our wrapper, of sorts, let’s set a width and background color.

body {
  width: 700px;
  margin: auto;
  background: #e3e3e3;
}

Now, we’ll float the primary content and the sidebar to the left and right, respectively. Also, as we’re not working with any real content, we’ll set a height to each container to present the illusion of content. This itself won’t be enough; we must also specify precisely how wide each should be. Otherwise, they’ll take up all of the available space, due to their block nature.

#primary {
 float: left;
 width: 75%;
 height: 500px;

 background: red;
}

aside {
 display: block; /* Because is HTML5 element */
 float: right;
 width: 25%;
 height: 500px;

 background: green;

}

Step 3. The Rub

So, all this looks just fine — for now. However, issues arise as soon as the height of the primary content exceeds the height of the sidebar. Further, this will typically be the case in most situations.

To simulate added content, let’s increase the height of the #primary div to be 700px.

Typically, the solution to these types of dilemmas is to apply a background image to the parent (#main) element. This will usually be a small slice of the background, which will then be vertically repeated.

#main {
...
background: url(small/slice/of/background.png) repeat-y;

}

Problem solved! Well, not exactly. True, this does work, however, as soon as you decide to change a background color, you’re then forced to return to Photoshop to create a new background image. What a drag!

Another common solution is to use JavaScript to dynamically detect the width of each container, and then make them the same height. Keep in mind that this then requires your layout to be dependent upon JS being enabled.

Step 4. The Solution

If we want to be forward thinkers, we can use CSS3 gradients to achieve this effect. What is that you say? “But Jeff, these are solid colors; not gradients!” True, but I’ll show you a little trick I learned. If you create two stops at the same location in a CSS3 gradient, you’ll end up with two solid colors. That’s a bit confusing; let me demonstrate.

Before we continue, if you’re working along, return to your project, and remove the background colors. They’re no longer needed. Now, we’ll add a background gradient to the parent, #main, container instead.

#main {
   background: -moz-linear-gradient(left, red, green);
}

So, that’s probably what you were expecting. But how will that help us? We need a distinct separation between the primary content and the sidebar.

This time, let’s specify that both the red and the green color-stops should be placed at the 75% marker.

#main {
   background: -moz-linear-gradient(left, red 75%, green 75%);
}

Isn’t that awesome? Not only are we using a gradient to create solid colors, ironically, but, also, the heights of each child container are now identical.

Keep in mind that this isn’t entirely accurate. They have the illusion of being the same height. In truth, though, we’re only applying a background to the parent element. The sidebar is still shorter; you just can’t tell.


Step 5. Webkit

The final step is to make Webkit browsers (Safari and Chrome) happy. Unfortunately, they don’t quite agree with Mozilla on the correct syntax for creating gradients. Their method isn’t quite as succinct as Mozilla’s.

#main {
   background: -moz-linear-gradient(left, red 75%, green 75%);
   background: -webkit-gradient(linear, left top, right top, from(red), color-stop(.75, red), color-stop(.75, green));
}

If you’re used to the from() and to() functions, keep in mind that they’re simply helper functions, which direct to color-stop().

color-stop accepts two parameters:

  • The position to stop
  • The desired color

To clarify, color-stop(.75, green) means, “at 75% of the width of the element, the color should now be green.” So yes, the syntax is different, but it only takes a few seconds to convert.


Conclusion

That’s all there is to it! Please remember that these are CSS3 techniques, meaning, IE is left out in the cold. Keep in mind, though: “not all websites must look identical in every browser.”

What do you think? Will you use this method, knowing that you’ll have to provide a fallback color for IE, or resort to using conditional statements to use a fallback image?

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://laroouse.com piyansitll

    very good tuts thanks a lot

    • Vipul Sharma

      yeah its nice tut..

      • ram

        good site..

  • http://www.shaneparkerphoto.com Shane Parker

    This is really cool, Jeffrey! I can’t wait until IE9 takes over older IE versions so we don’t have to use downgrade tricks. Things like this gradient trick would be so useful if it weren’t for IE :~(

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

    I’m not sure what the current state of CSS3 gradients is. I need to check what the spec recommends, in terms of syntax.

  • http://ghostbyte.com Morgan O’Neal

    Brilliant idea! Thanks for the tutorial.

  • http://twitter.com/jonathanulco Jonathanulco

    Some defects occur rendering on Chrome, but not on Safari and Firefox !
    (and no support gradient on Opera)

  • http://eisabainyo.net/weblog/ ESN

    Interesting method. Shame IE doesn’t support it. I don’t think I will use it just yet because I can achieve the same result in one line of CSS for all browsers by using a background image approach.

    • http://www.petarzivkovic.com Petar Zivkovic

      Yep. good point.

      After all, how often do you really have to make changes to the background? You’re better off sticking to the tried and true method… it provides more reliable results.

  • Karl Ballard

    Very useful and I am sure to use that very soon!

  • Eduardo Barros

    Hey guys, good news – IE6 and above can, in fact, support gradients.
    I suggest using css3pie.com, it adds a lot of CSS3 neat things to IE6+.

  • http://www.iamchad.com Chad

    Great tip! I love hearing about ways to use CSS3 to make things easier.

  • http://css-tricks.com Chris Coyier

    I’m not sure if Doug was the “first ever” to try it, but the first time I ever heard of it was in a conversation I had with Doug Neiner, and hence I dubbed this “The Doug Neiner Method” =) http://css-tricks.com/fluid-width-equal-height-columns/

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

      That’s a good article Chris.

      Just to clarify – I wasn’t implying that I invented this method (think I mention it in the video somewhere that the technique is making the rounds).

      Though, I must admit, that I taught this technique in one of those PSD->HTML type videos around a year ago. Or it might have been one of the multiple-borders quick tips from months ago. So, if he came up with it that far back, maybe I did learn it from him, and just forgot. :D

      • Jeffrey Way

        Here’s another article I wrote back in April or May that uses “this two colors in a gradient set to the same percentage” trick. :) http://net.tutsplus.com/tutorials/html-css-techniques/build-kick-ass-practical-css3-buttons/ – That was a fun little experiment. I still think the idea of using custom font glyphs in place of images hasnt fully been taken advantage of yet.

        Oh P.S. – Congrats on the new Lynda series, dude! Ive been meaning to watch it. Seems that Lynda made a big WP push this month, as I think they added three new series. That’s smart of them.

      • http://css-tricks.com Chris Coyier

        It’s cool to note that the same-percentage gradient trick works in fluid-width environments as well. Good move on the browser vendors part to have gradients be self aware and willing to redraw themselves when their parent changes.

        I imagine you’ve seen this for font-glyph icons: http://pictos.drewwilson.com/ I think it’s pretty clever idea as well. We used them for an internal project at Wufoo to awesome effect.

        Thanks on the new course. You know exactly how much work those super long training courses can be. Nice to have it finally out there.

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

        Oh no – I didn’t know that he had a font-glyph version of those icons. That’s pretty awesome. I’m trying to remember where I first read about using font glyphs in place of images. It was on somebody’s blog. Anyhow, there was a bunch of debate as to whether the size of font file would exceed the size of simply using a sprite.

        But, it’s *so* much more flexible…

      • Chris

        Can I just admit that seeing two of my favorite designers/developers/teachers talking to each other on here got me all giddy?

        Let the nerdy love abound.

      • arnold

        @the otherChris yeah this two guys are awesome XD…I learned a lot from both of them…

  • http://www.flickr.com/mikkelz/ Michael Thorne

    As mentioned by Jonathanulco: When the page first loads in Chrome 6.0.472.53 it appears correct. But as soon as you scroll down to the bottom of the page and then back up, the Primary (red) column starts to overlap the Sidebar (green) column about 20 pixels down from the top.

    Otherwise it’s pretty neat. ;)

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

      That’s odd. I’m on Chrome 7 right now, and it’s not doing that.

      • http://egorbrandt.nl egorbrandt

        On Chrome: scrolling up and down leads to the primary column overlapping the sidebar at different places.
        On Firefox: perfect!

      • http://twitter.com/immysl immysl

        Yes, I can confirm that it happens on Chrome 7 on Ubuntu.

    • Chris

      I am also showing this defect on Windows XP and Chrome 7

      • http://pippinspages.com Pippin

        I see the exact same thing in Chrome 7 on Windows 7.

    • http://benstokoe.co.uk Ben Stokoe

      The exact same thing happens for me, makes it look like a puzzle piece. And then the text in the green section enters the red section. Weird.

  • CosmoCoder

    As a few people have said above, this trick won’t work in IE ( without some script like CSS3 PIE ).
    So as a better workaround I suggest that you position the sidebar absolutely to the right of #main, which has to be positioned relatively. The essential styling that has to be applied is :

    #main {
    width: 700px;
    position: relative;
    }

    #primary {
    width: 75%;
    height: 700px;
    background: red;
    }

    #aside {
    display: block; /* Because is HTML5 element */
    width: 25%;
    position: absolute;
    right: 0;
    top: 0;
    bottom: 0;
    background: green;
    }

    Doing so will then force the sidebar to stretch and it will be as long as #main is. This will even work in IE, though I don’t know about IE6 :) .

  • http://jonjaques.com Jon Jaques

    Although this isn’t a perfectly semantic way to do it, Matthew Taylor has a solution that is 100% cross-browser with no css hacks.

    http://matthewjamestaylor.com/blog/equal-height-columns-cross-browser-css-no-hacks

  • http://webcloud.se/ Daniel

    Too bad pixel based color stops only works in firefox at the moment. Correct me if I’m wrong.

  • http://www.markdijkstra.eu Mark Dijkstra

    Nice one Jeff!

  • Dion Jensen

    Nice quicktip.

    However, if you absolutely want to use background gradients in IE, i recommend http://css3pie.com/
    I use it myself on a few sites and have yet to have any real issues (Except those mentioned on the site).

  • KoleS46

    Too bad it does not work in chrome 9 the example when i open it in a new tab i get red and green columns without any gradient ;(

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

      Well that’s what is supposed to happen.

  • http://www.taylorkearns.com TK

    Thanks for the tut. Why do we need to include

    #main { overflow: hidden; }

    in order to see the background color?

    • Chris

      It’s one of those tricks to contain floats. Otherwise the floats will collapse (the browser thinks they have no dimensions), you will see the text, but no coloration.

      Someone correct me if I’m wrong. I think you could also float the outer div#main to contain it as well. But then you have positioning and width issues.

      • Kit

        I believe so. In addition, there is the “clear:both on a trailing child element” for doing the same.

  • jack

    It is amazing that all this can be simplified by just using a table with Height set to 100% to position your containers and then using divs for content…..but nooooooooo….we have to have our web standards. What a bunch of bull.

    p.s – Is it really that taboo?

  • http://freeps3gamesnow.weebly.com/ PS3

    Awesome post! =D

  • http://geekandweb.blogspot.com esteban saxton

    nice information, thx a lot.

  • http://www.xeoscript.com Muhammed K K

    Thanks Jeffry, Nice tutorial

  • design

    Very nice .I will try it.

  • http://www.virtualidstudios.com David

    That’s effin’ brilliant! I spent hours trying to work up a good solution to this a couple weeks back. Considering my situation, it wasn’t worth redoing a ton, and the chances it would happen were very slim, but my conscience was bothering me as I knew it could possibly break in the future.

    And voila! Here you come with a brilliant solution! All I needed was the title, and I don’t even need to read the article! Thanks!

    Yay for the ultimate css gradient generator to make a life a lot simpler too!

  • http://twitter.com/edgarascom Edgaras Designer

    Nice method, I was always breaking my head with this one, and always ended up just using image :)