Search code examples
htmlcssfluid-layout

Fluid width with equally spaced DIVs


I have a fluid width container DIV.

Within this I have 4 DIVs all 300px x 250px...

<div id="container">
   <div class="box1"> </div>
   <div class="box2"> </div>
   <div class="box3"> </div>
   <div class="box4"> </div>
</div>

What I want to happen is box 1 to be floated left, box 4 to be floated right and box 2 and 3 to be spaced evenly between them. I want the spacing to be fluid as well so as the browser is made smaller the space becomes smaller also.

enter image description here


Solution

  • See: http://jsfiddle.net/thirtydot/EDp8R/

    • This works in IE6+ and all modern browsers!
    • I've halved your requested dimensions just to make it easier to work with.
    • text-align: justify combined with .stretch is what's handling the positioning.
    • display:inline-block; *display:inline; zoom:1 fixes inline-block for IE6/7, see here.
    • font-size: 0; line-height: 0 fixes a minor issue in IE6.

    #container {
      border: 2px dashed #444;
      height: 125px;
      text-align: justify;
      -ms-text-justify: distribute-all-lines;
      text-justify: distribute-all-lines;
      /* just for demo */
      min-width: 612px;
    }
    
    .box1,
    .box2,
    .box3,
    .box4 {
      width: 150px;
      height: 125px;
      vertical-align: top;
      display: inline-block;
      *display: inline;
      zoom: 1
    }
    
    .stretch {
      width: 100%;
      display: inline-block;
      font-size: 0;
      line-height: 0
    }
    
    .box1,
    .box3 {
      background: #ccc
    }
    
    .box2,
    .box4 {
      background: #0ff
    }
    <div id="container">
      <div class="box1"></div>
      <div class="box2"></div>
      <div class="box3"></div>
      <div class="box4"></div>
      <span class="stretch"></span>
    </div>

    The extra span (.stretch) can be replaced with :after.

    This still works in all the same browsers as the above solution. :after doesn't work in IE6/7, but they're using distribute-all-lines anyway, so it doesn't matter.

    See: http://jsfiddle.net/thirtydot/EDp8R/3/

    There's a minor downside to :after: to make the last row work perfectly in Safari, you have to be careful with the whitespace in the HTML.

    Specifically, this doesn't work:

    <div id="container">
        ..
        <div class="box3"></div>
        <div class="box4"></div>
    </div>
    

    And this does:

    <div id="container">
        ..
        <div class="box3"></div>
        <div class="box4"></div></div>
    

    You can use this for any arbitrary number of child divs without adding a boxN class to each one by changing

    .box1, .box2, .box3, .box4 { ...
    

    to

    #container > div { ...
    

    This selects any div that is the first child of the #container div, and no others below it. To generalize the background colors, you can use the CSS3 nth-order selector, although it's only supported in IE9+ and other modern browsers:

    .box1, .box3 { ...
    

    becomes:

    #container > div:nth-child(odd) { ...
    

    See here for a jsfiddle example.