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.

在这里输入图像描述


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 display:inline-block; *display:inline; zoom:1 fixes inline-block for IE6/7, see here.
  • font-size: 0; line-height: 0 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 easiest way to do this now is with a flexbox:

    http://css-tricks.com/snippets/css/a-guide-to-flexbox/

    The CSS is then simply:

    #container {
        display: flex;
        justify-content: space-between;
    }
    

    demo: http://jsfiddle.net/QPrk3/

    However , this is currently only supported by relatively recent browsers (http://caniuse.com/flexbox). Also, the spec for flexbox layout has changed a few times, so it's possible to cover more browsers by additionally including an older syntax:

    http://css-tricks.com/old-flexbox-and-new-flexbox/

    http://css-tricks.com/using-flexbox/


    If css3 is an option, this can be done using the css calc() function.

    Case 1: Justifying boxes on a single line ( FIDDLE )

    Markup is simple - a bunch of divs with some container element.

    CSS looks like this:

    div
    {
        height: 100px;
        float: left;
        background:pink;
        width: 50px;
        margin-right: calc((100% - 300px) / 5 - 1px); 
    }
    div:last-child
    {
        margin-right:0;
    }
    

    where -1px to fix an IE9+ calc/rounding bug - see here

    Case 2: Justifying boxes on multiple lines ( FIDDLE )

    Here, in addition to the calc() function, media queries are necessary.

    The basic idea is to set up a media query for each #columns states, where I then use calc() to work out the margin-right on each of the elements (except the ones in the last column).

    This sounds like a lot of work, but if you're using LESS or SASS this can be done quite easily

    (It can still be done with regular css, but then you'll have to do all the calculations manually, and then if you change your box width - you have to work out everything again)

    Below is an example using LESS: (You can copy/paste this code here to play with it, [it's also the code I used to generate the above mentioned fiddle])

    @min-margin: 15px;
    @div-width: 150px;
    
    @3divs: (@div-width * 3);
    @4divs: (@div-width * 4);
    @5divs: (@div-width * 5);
    @6divs: (@div-width * 6);
    @7divs: (@div-width * 7);
    
    @3divs-width: (@3divs + @min-margin * 2);
    @4divs-width: (@4divs + @min-margin * 3);
    @5divs-width: (@5divs + @min-margin * 4);
    @6divs-width: (@6divs + @min-margin * 5);
    @7divs-width: (@7divs + @min-margin * 6);
    
    
    *{margin:0;padding:0;}
    
    .container
    {
        overflow: auto;
        display: block;
        min-width: @3divs-width;
    }
    .container > div
    {
        margin-bottom: 20px;
        width: @div-width;
        height: 100px;
        background: blue;
        float:left;
        color: #fff;
        text-align: center;
    }
    
    @media (max-width: @3divs-width) {
        .container > div {  
            margin-right: @min-margin;
        }
        .container > div:nth-child(3n) {  
            margin-right: 0;
        }
    }
    
    @media (min-width: @3divs-width) and (max-width: @4divs-width) {
        .container > div {  
            margin-right: ~"calc((100% - @{3divs})/2 - 1px)";
        }
        .container > div:nth-child(3n) {  
            margin-right: 0;
        }
    }
    
    @media (min-width: @4divs-width) and (max-width: @5divs-width) {
        .container > div {  
            margin-right: ~"calc((100% - @{4divs})/3 - 1px)";
        }
        .container > div:nth-child(4n) {  
            margin-right: 0;
        }
    }
    
    @media (min-width: @5divs-width) and (max-width: @6divs-width) {
        .container > div {  
            margin-right: ~"calc((100% - @{5divs})/4 - 1px)";
        }
        .container > div:nth-child(5n) {  
            margin-right: 0;
        }
    }
    
    @media (min-width: @6divs-width){
        .container > div {  
            margin-right: ~"calc((100% - @{6divs})/5 - 1px)";
        }
        .container > div:nth-child(6n) {  
            margin-right: 0;
        }
    }
    

    So basically you first need to decide a box-width and a minimum margin that you want between the boxes.

    With that, you can work out how much space you need for each state.

    Then, use calc() to calcuate the right margin, and nth-child to remove the right margin from the boxes in the final column.

    The advantage of this answer over the accepted answer which uses text-align:justify is that when you have more than one row of boxes - the boxes on the final row don't get 'justified' eg: If there are 2 boxes remaining on the final row - I don't want the first box to be on the left and the next one to be on the right - but rather that the boxes follow each other in order.

    Regarding browser support : This will work on IE9+,Firefox,Chrome,Safari6.0+ - (see here for more details) However i noticed that on IE9+ there's a bit of a glitch between media query states. [if someone knows how to fix this i'd really like to know :) ] <-- FIXED HERE

    链接地址: http://www.djcxy.com/p/88274.html

    上一篇: 让柔性盒中剩余的*水平*空间填充div

    下一篇: 具有等间距DIV的流体宽度