Liquid layouts the easy way

Date: 30 December 2003
Author: Russ Weakley

This article explains one method of achieving a successful liquid layout as well as providing basic definitions of liquid, fixed-width and em-driven layouts.

Some definitions

Liquid layout

All containers on the page have their widths defined in percents – meaning that they are completely based on the viewport rather than the initial containing block. A liquid layout will move in and out when you resize your browser window.

Combination liquid and fixed layouts

Similar to liquid layouts, except one or more of the containers on the page have fixed widths.

Fixed-width layouts

All containers on the page have their widths defined in pixels or other fixed units. They are completely independent of the viewport. A fixed layout will not move in and out when you resize your browser window.

Em-driven layouts

All containers on the page have their widths defined in ems. They will be scaled according to the users default browser font size. They are completely independent of the viewport.

You can also use combinations of the above.

The secret of liquid layouts

Liquid layouts are easy to achieve if you follow some basic rules.

  1. work out a basic layout grid before you begin coding
  2. include gutters so that your columns will not spread too wide
  3. use percentage units for widths of all containers and gutters
  4. do not define containers that use the full width of a page – allow for browser rendering issues (such as percentage rounding)

Step 1 – Start with a layout grid

It is a good idea to start by sketching (on paper or using some imaging software) a rough layout grid.

You can start by doing a grid at 800 pixels wide. Columns and gutters can be adjusted until you are happy with the layout. When happy, these pixel-based measurements are then converted to percentage units.

If you want to achieve a basic three-column layout, your sketch could look like this:

Liquid layout sample

The basic column grid for this mockup is:

column pixel width percentage width
gutter 1 24px 3%
column 1 384px 48%
gutter 2 24px 3%
column 2 160px 20%
gutter 3 24px 3%
column 3 160px 20%
gutter 4 24px 3%
total 800px 100%

As you can see, there has been an allowance made for gutters between each column. This will add some space to the page and stop the columns from becoming too wide in very wide browser windows. This is important, as line length affects readability.

Step 2 – Leaving space

One problem with percentage widths is that they have to be calculated by the browser so there will be some degree of rounding up or down of the percentage measurements. For this reason, it is always good to leave some free space on the page so there is room for error. In this case, you will simply leave "gutter 4" undefined, so there is 3% of free space at the right of the layout.

column percentage width
gutter 1 3%
column 1 48%
gutter 2 3%
column 2 20%
gutter 3 3%
column 3 20%
gutter 4 undefined
total 97%

Step 3 – Making containers

You now have three gutters and three columns. The gutters can be converted to left margins for each of the columns:

column margin-left column width total width
column 1 3% 48% 51%
column 2 3% 20% 23%
column 3 3% 20% 23%
total 97%

These three columns can be converted into <div> containers. You can then apply a width, “margin-left” and “float: left” to each of them:

HTML code

<body>
<div id="col1"></div>
<div id="col2"></div>
<div id="col3"></div>
</body> 

CSS code

#col1
{
	float: left;
	width: 48%;
	margin-left: 3%;
}
	
#col2
{
	float: left;
	width: 20%;
	margin-left: 3%; }

#col3
{
	float: left;
	width: 20%;
	margin-left: 3%;
}

Step 4 – Fixing an Internet Explorer bug

You may have noticed that there is a problem with the sample above in Internet Explorer 5, 5.5 and 6 for Windows. The left margin is wider in these browsers. Internet Explorer 5, 5.5 and 6 for Windows have issues with margins applied to floated items that touch the left or right edge of the viewport. These browsers will sometimes double these margin widths – so a 3% left-margin will become a 6% left-margin.

All other standards-compliant browsers will render a 100px left margin, but Internet Explorer 5, 5.5 and 6 for Windows will render a 200px wide margin.

This rendering issue can sometimes cause the third column to drop below the other two columns. Luckily, there is a work-arounds for this problem. In this case you can add "display: inline" to column 1 and the double float bug will disappear in Internet Explorer 5, 5.5 and 6.. The code is now:

HTML code

<body>
<div id="col1"></div>
<div id="col2"></div>
<div id="col3"></div>
</body>

CSS code

#col1
{
	float: left;
	width: 48%;
	margin-left: 3%;
	display: inline;
}
	
#col2
{
	float: left;
	width: 20%;
	margin-left: 3%;
}
	
#col3
{
	float: left;
	width: 20%;
	margin-left: 3%;
}

Step 5 – Adding headers and footers

It is easy to add headers and footers to this example. The header <div> will naturally sit above these floated columns and gutters as long as it is not floated. The footer must be cleared from the floated item by applying “clear: both”. There are now 5 <div> containers on the page:

HTML code

<body>
<div id="header"></div>
<div id="col1"></div>
<div id="col2"></div>
<div id="col3"></div>
<div id="footer"></div>
</body> 

CSS code

#header
{
	margin-bottom: 10px;
}
	
#col1
{
	float: left;
	width: 48%;
	margin-left: 3%;
	display: inline;
}
	
#col2
{
	float: left;
	width: 20%;
	margin-left: 3%;
}
	
#col3
{
	float: left;
	width: 20%;
	margin-left: 3%;
}
	
#footer
{
	clear: both;
} 

Step 6 – Working around the box model

If you want to inset text within these three columns and you want to apply padding to the containers, you need to remember that Internet Explorer 5 and 5.5 for Windows incorrectly render the box model.

One way to avoid this problem is apply padding to items within the containers rather than to the containers themselves. This can be done with a rule set such as:

h2, p
{
	margin-left: 7px;
	margin-right: 7px;
} 

Or, if you want to be more specific, you can choose to target a specific column:

#col1 h2, #col1 p
{
	margin-left: 7px;
	margin-right: 7px;
}

Final result

Once you have established the basic layout, you can swap columns, or add borders as needed:

Liquid insanity

When you understand how to set up column widths for liquid layouts, it becomes easy to do more advanced layouts with multiple liquid options:

Comments so far

  1. Sam says:

    I really enjoy reading your articles, such clarity and efficiency, your students must have a great time with you guys.

  2. Russ says:

    @Sam, thanks for the kid words- glad you found it clear and efficient! ;)

  3. Laine says:

    I’ve been wanting to learn tableless CSS for ages and this actually makes it all make sense! Very clear. Thank you thank you thank you!!!!

    (I hate messing with tables)!

  4. Naveed says:

    Really Good Tutorial.

  5. linda duffy says:

    Thankyou so much… very clear …and so straight forward…no more head wrecks…

  6. Russ says:

    @linda, thanks for the feedback. More layouts here:http://www.maxdesign.com.au/articles/css-layouts/

  7. Essam Rashad says:

    Hi there!
    I will be extremely appreciative if you could post or send me the css/html code for “liquid insanity” if possible :P I am having trouble with positioning subsections.

    Of course, your tutorial is amazing,
    Thanks!

  8. Russ says:

    @Essam, The HTML and CSS code is now available on the Liquid Insanity page:
    http://www.maxdesign.com.au/articles/liquid/liquid-sample9/

  9. Edgar says:

    Hello there… very nicelty explained. My only problem is that the samples do not work quite well with FireFox. Is there any trick to be considered?

    Cheers

  10. Hi I am really stuck up at a problem,

    I needed a layout as :
    http://img535.imageshack.us/img535/5919/whatineed.jpg

    I tried my best but its not rendering fine in all browsers. please help me.

  11. Ant says:

    Thanks for all the great info. I’m a web design student, and I frequently come to here to get clarification about page layouts to help me complete my projects for school.

  12. Gianni C says:

    I have a dumb question lol…what are you doing to convert the pixels into a percentage? if 800px is 100%, how do you know 24px is 3%?

  13. Russ says:

    @Gianni C: In this case, it just happens that each number is divided by 8:

    24px / 8 = 3%
    384px / 8 = 48%
    24px / 8 = 3%
    160px / 8 = 20%
    24px / 8 = 3%
    160px / 8 = 20%
    24px / 8 = 3%
    800px = 100%

    However, it really doesn’t matter how you do it. The key is to make sure that it all adds up to 100% :)

  14. Agnes says:

    This is just what I need, I’ve tried many times to do CSS based layouts but with your lesson I’m sure that I also can do it by myself…

    Thank you. :-)

  15. HJ says:

    Thank U ~~ your articles are very so clear that I could understand “CSS layout”.

  16. NJ says:

    Thank U,

    Great and very clear article

    Thanks

  17. In this method, would you always use a float left — I am thinking yes, but if there is a case where you would set up the grid with a float right example, please do advise. And thanks…I have read, studied, “classed” and more and this is the best, simplest example I have seen. well done!

  18. I am really expect this kind of explanation. I am really happy to read it. Thanks

  19. Lukman says:

    On a normal day i won’t write anytin but i have to satisfy my mind. you did a good Job. You remind me of K.A Stroud(Engineering Maths)

  20. Guy says:

    Hi I am trying to convert this page http://eaglecoatings.net from 9 frame’s based layout to css having trouble with getting all the image in ??

  21. Dennis says:

    Great article! I really enjoyed reading it! But here is a challenge. How do we create liquid / fixed columns connected together? I’ve been trying to get left column fixed then footer and header being liquid without any spaces in between but of no avail… Generally speaking I am trying to get my design to have 3 stripes of the same color on the left(left fixed column), bottom(liquid footer), and top(liquid header) but cannnot seem to fix it… Any ideas anyone? Would appreciate any advise at all. Thanks

  22. Abhi says:

    Excellent Article:
    But can we start the 100% fluid layout directly or do we needs to first create a layout in pixels and then change it percentages

  23. Russ says:

    Hi Dennis,

    It is not so hard to do what you are asking.

    One solution would be to assume there are five containers
    - header – liquid full width
    - a content wrapper
    - left content column – fixed width – eg 200px
    - right content column – liquid remaining width minus left column
    - footer – liquid full width

    For example:

    <div id=”header”>/div>
    <div id=”content-wrapper”>
    <div id=”left”></div>
    <div id=”right”></div>
    </div>
    <div id=”footer”></div>

    Please note that these names are far from ideal – you would not normally name them based on appearance.

    To style these containers:

    1. allow the header to spread across the viewport as needed

    2. float “content-wrapper” and apply a repeating background image down the left edge of this container. For example

    #content-wrapper
    {
    float: left;
    width: 100%;
    background: url(image.jpg) repeat-y;
    }

    float the left content column and give it a width. For example:

    #left
    {
    clear: left;
    float: left;
    width: 200px;
    }

    3. leave the right content column in normal flow (ie do not float it) but set this container with a left margin so it is pushed away from the left edge – creating the illusion of a column. For example:

    #right
    {
    margin-left: 200px;
    }

    4. The footer would also need to be given a clear. For example:

    #footer
    {
    clear: left;
    }

    That should do the trip.

    Be aware that the right column is in normal flow so anything set to clearl elft with also clear the entire left column.

    HTH

  24. Russ says:

    Abhi

    You do not need to start with a pixel version at all. The reason I suggested this is because a lot of designers start with photoshop files where they have had to define aspects of the page in pixels first.

    however, you can simply create a liquid layout using percentages straight away.

    HTH

  25. Dennis says:

    Hi Russ!

    Many thanks for your reply! It helped me out to find my mistake! I set my left column’s background repeat-y property but it did not work. It looks like I had to do it via wrapper’s container as per your suggestion. I gave it a try and it really did the trip! Fantastic! Now my design is finished. However, I was also wondering if you could possibly take a look at my entire CSS style sheet and its URL? The matter is that my other containers’ top-margin properties’ are set to -8% and -120px which makes me worried if that may result in any distorted outputs in IE6. Plus I think there might be some other tiny mistakes even though it all works fine now except for top-container’s non-resizable image set for background… I’d really do appreciate!

  26. Dennis says:

    Hi Russ,

    No worries! Even though I got stuck with my old design and I can not seem to find where I made this darn mistake either in my code or CSS I went so excited about your samples that I have decided to use the one of them! Since it says,
    ” *quote they are free to use and abuse if needed” *unquote I basically changed the colors only as everything else fits in just perfectly! I realy do thank you indeed for being so really generous by allowing your web-sie’s visitors to use your Cascading Style Sheets.

  27. Russ says:

    All my articles and presentations are available free to use and abuse as needed. :)

  28. ccomeout says:

    Very good tutorial on fluid layout. Especially how to solve the problem on IE 5.5, 6. Thank you.

  29. Suzan says:

    This is one of the best tutorials I have used. It is very kind of you to spend time creating these resources.

  30. Jan says:

    Excellent tutorials, Russ :)
    Could you please post the code for the liquid layout with the borders only? Just having a bit of trouble trying to get borders nicely in the middle… is their some sort of magic formula, or just a case of padding? (as I have been doing, but being pedantic I just wanted to check with you)

  31. Russ says:

    Hi Jan, the code has now been added to the borders version.

  32. Jaganathan says:

    Hi – You saved my day. Thanks a lot.

  33. Tony says:

    I tried your “two column fixed width (with spread) layout” and it works perfectly in Firefox, but not in IE. Even if I copy and paste the code you kindly shared it doesn’t work. In IE it doesn’t look centered, it aligns to the left. I’m using it in antonioromo.com. Am I missing something? Thanks!!

  34. Laurie says:

    Am finally making time to go thru and change all my includes with tables to CSS. I loved this article as it explained exactly what I wanted to do. Keep up the good work, mate!

  35. David says:

    Hi. Just like to say thanks for the clear and useful info about liquid layouts.
    I have set my index page in a liquid layout. However, I was wondering, if I have an image that is set as 40% of the screen width. Can I set the height of the image to be relative to the width? Foe example; if the screen width is 1000px and the width is 40% = 400px I want the height of the image to be 400px too in order to remain square. I don’t want my image to get squashed in strange browers settings.

  36. ianstudio says:

    Hi, thanks for the tutorials on here.. I’m a Flash designer who really loves liquid layouts (and hates scrollers) and am trying to see what can be achieved with HTML/CSS.. Is there any way you could provide samples of “liquidity” vertically as well… I often see horizontal (width) liquid layouts but never vertical ones.. except for the odd footer that remains visible..

    THX

  37. Russ says:

    @David,

    You can apply this method to the image, but the critical thing is to leave the width and height undefined. For example:

    Defined:
    <img src=”image.gif” alt=”" width=”50″ height=”50″ />

    Undefined:
    <img src=”image.gif” alt=”" />

  38. Will says:

    Thank heaven that someone has finally done a good tutorial site on this matter. Even today with the prominence of the web as it is, there is so much ambiguity relating to this topic and for a budding web programmer it is infuriating! Thanks again Russ, spot on!

  39. Helena says:

    Now this is brilliant, I have been googling and selft taught myself html… doing alright but fixing older browsers’s bugs have been dirving me nuts… and her you are: a simple line of code. BRILLIANT!!! and text for the formula for the margin, these puzzled me for a while as well. You made my day

  40. Russ says:

    Glad you found it useful, Helena. :)