2

I'm going around in circles trying to figure this out.

HTML/CSS:

<style type='text/css'>

#content {
    padding: 20px;
    background: #F3F6F7;
}

.inner-box {
    background: #fff;
}

.inner-box .col {
    background:#eee;
    display:block;
    float:left;
    margin:1%;
    padding:20px;
    width:23%;
}

</style>

<div id="content">      
    <div class="inner-box clearfix">
        <div class="col col-1">
            COl1
        </div>
        <div class="col col-2">
            COl2
        </div>
        <div class="col col-3">
            COl3
        </div>
        <div class="col col-4">
          COl4
        </div>

    </div>              
</div>    

I basically want a fluid 4 column layout with an equal bit of padding around each column and the whole thing to span 100% across the screen.

The code above works but as soon as i scale the browser the 4th column on the right will shift down under the rest.

Rajat Jain
  • 1,339
  • 2
  • 16
  • 29
Carpy
  • 1,054
  • 6
  • 17
  • 35

6 Answers6

6

Personally I've given up on using floats. I find them too temperamental to work with.

I now use display: inline-block; in the place of floats. Note that IE7 and below doesn't support this, but there is an exceptional css hack that works perfectly. Use conditional comments and a separate CSS file for IE7 and below.

The Cross-browser Inline-Block hack is fantastic for getting around this.

For all of my projects, I define an inline-block class.

.inline-block
{
    display: inline-block;
}

and in the IE CSS file, I have:

.inline-block
{
    zoom: 1;
    *display: inline;
}

You can then layout any fluid layouts easy, placing the divs side-by-side and setting a percentage width for each one. I usually define a class that denotes a fixed percentage width

.twenty-five-perc
{
    width: 25%;
}

So your resulting html might look like this:

<div>
    <div class="inline-block twenty-five-perc">
    </div><div class="inline-block twenty-five-perc">
    </div><div class="inline-block twenty-five-perc">
    </div><div class="inline-block twenty-five-perc">
    </div>
</div>

Now you might wondering why I have the opening div tags on the same line as the previous closing tag. This is because inline-block respects whitespace and this will break the layout. You can read more about this issue and ways to mitigate it here: http://www.lifeathighroad.com/web-development/css-web-development/inline-block-whitespace-workaround/

Fair bit of rambling here, but the upshot is You can do really nice fluid layouts without having to dick around with float layouts.

Alastair Pitts
  • 19,423
  • 9
  • 68
  • 97
  • Note that there are also some incompatibilities between browsers relating to [baseline alignment](https://bugs.webkit.org/show_bug.cgi?id=36084) if you have `overflow:hidden` set on any of the elements. – robertc Nov 25 '10 at 23:04
  • Your answer is complete and it works. My only problem is that `class="inline-block twenty-five-perc"` isn't very semantic. You might as well put it in a style attribute :) – Jan Nov 25 '10 at 23:18
  • @jan: I agree with the `twenty-five-perc`, it's a personal affectation, but the `inline-block` is needed to be defined for the IE hack to be site wide. – Alastair Pitts Nov 26 '10 at 00:07
  • @Alstair: It is needed in CSS, but in the Html you can still give it a more descriptive classname in stead of `class="inline-block"`. Aside from that I am convinced that this particular example would be better of with absolute positioning. – Jan Nov 27 '10 at 16:31
3

A few thoughts.

First, you don't need the clearfix div. Using overflow:hidden on #content is a better way to handle this. So your HTML looks like this:

<div id="content">      
    <div class="col col-1">
        COl1
    </div>
    <div class="col col-2">
        COl2
    </div>
    <div class="col col-3">
        COl3
    </div>
    <div class="col col-4">
      COl4
    </div>             
</div>

That's cleaner. Secondly, divs are block-level elements, so display:block; is unnecessary.

Also, unless you use flexible units for your gutters, you'll run into a problem when the viewport becomes smaller than your column percentages allow. I would suggest using percentages for the gutters. Remember that percentages are percentages in relation to the parent element, so .col will be a percentage of #content.

Since you're using floats and each column has its own class available, it's easy to add the gutter as a right-margin, and set it to 0 on the last one.

So not only is your markup simpler, but the CSS as well:

content {
  padding: 20px;
  background: #F3F6F7;
  overflow:hidden;
  }
.col {
  background:#eee;
  float:left;
  width:22%;
  margin-right: 4%;
  }
.col-4 {margin-right:0;}

Also note how (22% * 4) + (4% * 3) = 100%.

Hope this helps. See http://jsfiddle.net/D759g/ for a working example.

stephenhay
  • 2,824
  • 24
  • 25
  • BTW, inline-block, as Alastair points out, is also a fine way to do this. I gave this example assuming you're willing or wanting to use floats. Either are workable in most browsers. – stephenhay Nov 25 '10 at 22:33
1

I would use absolute positioning in this layout. In my opinion the most reliable solution. Plus you can change the padding without breaking your layout. Plus you can add border and margin, no problem.

/* assuming your html is under the body tag */
html, body, #content, .inner-box { margin: 0px; height: 100%; }

.inner-box { position: relative; }

.col {
  position: absolute;
  top: 0px; bottom: 0px;
  padding: 1%;
  border: 1px solid black;
}

.col-1 { left: 0%; right: 75%; }

.col-2 { left: 25%; right: 50%; }

.col-3 { left: 50%; right: 25%; }

.col-4 { left: 75%; right: 0%; }

note that the left value of a column and the right value of the previous column always add up to 100%

NOTE: this doesn't work in ie6.

Jan
  • 8,011
  • 3
  • 38
  • 60
  • Just experimenting with this layout. Works well but because it's positioned absolute, how do you clear so the inner-box flows past the columns ? – Carpy Dec 08 '10 at 14:45
  • I don't understand your question. Nothing is floated in this layout. Just replace your CSS in the sample with mine. Clearing floats is a bad practice by the way. Use `overflow: auto;` on a container to wrap it around floating content. – Jan Dec 08 '10 at 14:55
  • 'Clearing floats with empty or invisible elements to make the container wrap around the content' is what I meant of course. – Jan Dec 08 '10 at 15:06
  • It seems that position absolute takes the cols out of the .inner-box wrap so the inner-box doesn't span past the col's anymore (height wise). It's like the height: 100% doesn't seem to do anything. – Carpy Dec 08 '10 at 19:14
  • Try this sample where I changed the background of .inner-box to red http://jsfiddle.net/FHN8F/2/. It works for me in Chrome, Firefox and ie8. (I found out there is an issue with it in Chrome: http://code.google.com/p/chromium/issues/detail?id=65912) – Jan Dec 08 '10 at 20:14
  • You're right. I think it must be conflicting with something else on my page which is causing the height: 100% to be ignored. I like this method though. Only issue is you have to name each col with a unique class, but thats minor. Thanks for the help. – Carpy Dec 09 '10 at 11:58
  • Use firebug or the Chrome developer tools to see what is happening in terms of CSS on your page. It should be easy to locate where the class is overriden. – Jan Dec 09 '10 at 15:17
0

I'd try with something a little less than 23%: DOM element borders, padding, margins, etc are added to the width of the element, instead of becoming part of the width. I assume you are scaling the browser down, which scales the percentages, but not the fixed pixel paddings, etcetera, meaning there is more padding relative to the internal width, making the columns a bit too large for the 100% width.

Hope this helps,

James

Bojangles
  • 99,427
  • 50
  • 170
  • 208
0

Having some values as a fixed pixels will cause you troubles.

Make sure all your paddings and margins and contents equal a total of 99% - I have have found Mozilla has trouble when all values equal 100%.

  <style type='text/css'>

    #content {
        padding: 1%;
        background: #F3F6F7;
    }

    .inner-box {
        background: #fff;
    }

    .inner-box .col {
        background:#eee;
        display:block;
        float:left;
        margin:1%;
        padding:1%;
        width:21%;
    }

    </style>
dpmguise
  • 718
  • 1
  • 4
  • 10
-1

Here's the easiest way to do a 2, 3, or 4 column list. Just adjust the percentages to equal 99% of the page (or 100 in this case).

<font size="4"><font color="maroon"><b>TITLE</b></font>  <font size="2"><div style="width: 25%; float: left;">
 <ul>
 <li>Left Item 1</li>
 <li>Left Item 2</li>
 <li>Left Item 3</li>
 <li>Left Item 4</li>
 <li>Left Item 5</li>
 </ul>
 </div>
 <div style="width: 25%; float: left;">
 <ul>
 <li>Left Item 1</li>
 <li>Left Item 2</li>
 <li>Left Item 3</li>
 <li>Left Item 4</li>
 <li>Left Item 5</li>
 </ul>
 </div>
 <div style="width: 25%; float: right;">
 <ul>
 <li>Right Item 1</li>
 <li>Right Item 2</li>
 <li>Right Item 3</li>
 <li>Right Item 4</li>
 <li>Right Item 5</li>
 </ul>
 </div> <div style="width: 25%; float: right;">
 <ul>
 <li>Right Item 1</li>
 <li>Right Item 2</li>
 <li>Right Item 3</li>
 <li>Right Item 4</li>
 <li>Right Item 5</li>
 </ul>
 </div></font></font>