[css] 2 column div layout: right column with fixed width, left fluid

My requirement is simple: 2 columns where the right one has a fixed size. Unfortunately I couldn't find a working solution, neither on stackoverflow nor in Google. Each solution described there fails if I implement in my own context. The current solution is:

div.container {
    position: fixed;
    float: left;
    top: 100px;
    width: 100%;
    clear: both;
}

#content {
    margin-right: 265px;
}

#right {
    float: right;
    width: 225px;
    margin-left: -225px;
}

#right, #content {
    height: 1%; /* fixed for IE, although doesn't seem to work */
    padding: 20px;
}
<div class="container">
    <div id="content">
        fooburg content
    </div>
    <div id="right">
        test right
    </div>
</div>

I get the following with above code:

|----------------------- -------|
| fooburg content  |            |
|-------------------------------|
|                  | test right | 
|----------------------- -------|

Please advise. Many thanks!

This question is related to css html

The answer is


Remove the float on the left column.

At the HTML code, the right column needs to come before the left one.

If the right has a float (and a width), and if the left column doesn't have a width and no float, it will be flexible :)

Also apply an overflow: hidden and some height (can be auto) to the outer div, so that it surrounds both inner divs.

Finally, at the left column, add a width: auto and overflow: hidden, this makes the left column independent from the right one (for example, if you resized the browser window, and the right column touched the left one, without these properties, the left column would run arround the right one, with this properties it remains in its space).

Example HTML:

<div class="container">
    <div class="right">
        right content fixed width
    </div>
    <div class="left">
        left content flexible width
    </div>
</div>

CSS:

.container {
   height: auto;
   overflow: hidden;
}

.right {
    width: 180px;
    float: right;
    background: #aafed6;
}

.left {
    float: none; /* not needed, just for clarification */
    background: #e8f6fe;
    /* the next props are meant to keep this block independent from the other floated one */
    width: auto;
    overflow: hidden;
}??

Example here: http://jsfiddle.net/jackJoe/fxWg7/


I'd like to suggest a yet-unmentioned solution: use CSS3's calc() to mix % and px units. calc() has excellent support nowadays, and it allows for fast construction of quite complex layouts.

Here's a JSFiddle link for the code below.

HTML:

<div class="sidebar">
  sidebar fixed width
</div>
<div class="content">
  content flexible width
</div>

CSS:

.sidebar {
    width: 180px;
    float: right;
    background: green;
}

.content {
    width: calc(100% - 180px);
    background: orange;
}

And here's another JSFiddle demonstrating this concept applied to a more complex layout. I used SCSS here since its variables allow for flexible and self-descriptive code, but the layout can be easily re-created in pure CSS if having "hard-coded" values is not an issue.


Simplest and most flexible solution so far it to use table display:

HTML, left div comes first, right div comes second ... we read and write left to right, so it won't make any sense to place the divs right to left

<div class="container">
    <div class="left">
        left content flexible width
    </div>
    <div class="right">
        right content fixed width
    </div>
</div>

CSS:

.container {
  display: table;
  width: 100%;
}

.left {
  display: table-cell;
  width: (whatever you want: 100%, 150px, auto)
}??

.right {
  display: table-cell;
  width: (whatever you want: 100%, 150px, auto)
}

Cases examples:

// One div is 150px fixed width ; the other takes the rest of the width
.left {width: 150px} .right {width: 100%}

// One div is auto to its inner width ; the other takes the rest of the width
.left {width: 100%} .right {width: auto}

Hey, What you can do is apply a fixed width to both the containers and then use another div class where clear:both, like

div#left {

width: 600px;
float: left;
}

div#right {

width: 240px;
float: right;

}

div.clear {

clear:both;

}

place a the clear div under left and right container.


Best to avoid placing the right column before the left, simply use a negative right-margin.

And be "responsive" by including an @media setting so the right column falls under the left on narrow screens.

<div style="background: #f1f2ea;">
  <div id="container">
    <div id="content">
        <strong>Column 1 - content</strong>
    </div>
  </div>
  <div id="sidebar">
    <strong>Column 2 - sidebar</strong>
  </div>
<div style="clear:both"></div>

<style type="text/css">
#container {
    margin-right: -300px;
    float:left;
    width:100%;
}
#content {
    margin-right: 320px; /* 20px added for center margin */
}
#sidebar {
    width:300px;
    float:left
}
@media (max-width: 480px) {
    #container {
        margin-right:0px;
        margin-bottom:20px;
    }
    #content {
        margin-right:0px;
        width:100%;
    }
    #sidebar {
        clear:left;
    }
}
</style>

See http://www.alistapart.com/articles/negativemargins/ , this is exactly what you need (example 4 there).

<div id="container">
    <div id="content">
        <h1>content</h1>
        <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.  Phasellus varius eleifend tellus. Suspendisse potenti. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Nulla facilisi. Sed wisi lectus, placerat nec, mollis quis, posuere eget, arcu.</p>
        <p class="last">Donec euismod. Praesent mauris mi, adipiscing non, mollis eget, adipiscing ac, erat. Integer nonummy mauris sit amet metus. In adipiscing, ligula ultrices dictum vehicula, eros turpis lacinia libero, sed aliquet urna diam sed tellus. Etiam semper sapien eget metus.</p>
    </div>
</div>

<div id="sidebar">
    <h1>sidebar</h1>
    <ul>
        <li>link one</li>
        <li>link two</li>
    </ul>
</div>

#container {
    width: 100%;
    background: #f1f2ea url(background.gif) repeat-y right;
    float: left;
    margin-right: -200px;
}
#content {
    background: #f1f2ea;
    margin-right: 200px;
}
#sidebar {
    width: 200px;
    float: right;

This is a generic, HTML source ordered solution where:

  • The first column in source order is fluid
  • The second column in source order is fixed
    • This column can be floated left or right using CSS

Fixed/Second Column on Right

_x000D_
_x000D_
#wrapper {_x000D_
  margin-right: 200px;_x000D_
}_x000D_
#content {_x000D_
  float: left;_x000D_
  width: 100%;_x000D_
  background-color: powderblue;_x000D_
}_x000D_
#sidebar {_x000D_
  float: right;_x000D_
  width: 200px;_x000D_
  margin-right: -200px;_x000D_
  background-color: palevioletred;_x000D_
}_x000D_
#cleared {_x000D_
  clear: both;_x000D_
}
_x000D_
<div id="wrapper">_x000D_
  <div id="content">Column 1 (fluid)</div>_x000D_
  <div id="sidebar">Column 2 (fixed)</div>_x000D_
  <div id="cleared"></div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

Fixed/Second Column on Left

_x000D_
_x000D_
#wrapper {_x000D_
  margin-left: 200px;_x000D_
}_x000D_
#content {_x000D_
  float: right;_x000D_
  width: 100%;_x000D_
  background-color: powderblue;_x000D_
}_x000D_
#sidebar {_x000D_
  float: left;_x000D_
  width: 200px;_x000D_
  margin-left: -200px;_x000D_
  background-color: palevioletred;_x000D_
}_x000D_
#cleared {_x000D_
  clear: both;_x000D_
}
_x000D_
<div id="wrapper">_x000D_
  <div id="content">Column 1 (fluid)</div>_x000D_
  <div id="sidebar">Column 2 (fixed)</div>_x000D_
  <div id="cleared"></div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

Alternate solution is to use display: table-cell; which results in equal height columns.


I have simplified it : I have edited jackjoe's answer. The height auto etc not required I think.

CSS:

#container {
position: relative;
margin:0 auto;
width: 1000px;
background: #C63;
padding: 10px;
}

#leftCol {
background: #e8f6fe;
width: auto;
}

#rightCol {
float:right;
width:30%;
background: #aafed6;
}

.box {
position:relative;
clear:both;
background:#F39;
 }
</style>

HTML:

<div id="container">

  <div id="rightCol"> 
   <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>

  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>
 </div>

 <div id="leftCol">

   <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>

  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>
  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>

Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.

</div>

</div>

<div class="box">
  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>

  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>
  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>
</div>