tags:

views:

391

answers:

4

Here is my scenario. I have a container div that has (n) child elements inside it. For this instance lets say there are 2 divs within the container div:

<div id="container">
    <div id="col1">
        Stuff in col1
    </div>
    <div id="col2">
        Stuff in col2
    </div>
</div>

The container div is going to be a percentage of the viewport, say 80%. Now, what I'm looking for is for these two inner divs (col1 & col2) to be inline with each other and take up the same amount of space. So the result should look something like this:

+-------------- container -------------+
|  +---- col1 ----+  +---- col2 ----+  |
|  | stuff in     |  | stuff in     |  |
|  | col1         |  | col2         |  |
|  +--------------+  +--------------+  |
+--------------------------------------+

Or if the container width is changed should result in something like this:

+------------------------------ container -----------------------------+
|  +------------ col1 ------------+  +------------ col2 ------------+  |
|  | stuff in col1                |  | stuff in col2                |  |
|  | stuff in col1                |  | stuff in col2                |  |
|  +------------------------------+  +------------------------------+  |
+----------------------------------------------------------------------+

The inner divs are always of equal width and have some separation from each other. This is similar to a table layout, but I would rather not use tables if possible. I have tried various techniques like floating and displaying the divs inline to no avail. They can never seem to align just right.

A: 

make col1 and col2 spans (not divs) with

vertical-align:top
display:inline-block
width:50%

obviously (adjust the width to account for your margins/padding. and recommended that you use percentages for margins/padding so they add up to just under 100% see:http://ejohn.org/blog/sub-pixel-problems-in-css/)

Jonathan Fingland
Thanks for the answer Jon. The reason they are divs is because they are going to contain more complex structures than text, but just for the sake of brevity, I used text in place. Would the same idea apply if they were to remain divs?
a span does not *have to* contain only text. the reason they would be spans and not divs is because IE refuses to apply inline-block to divs. in firefox you can make spans and divs (or anything) inline-block and it makes no difference except for the semantics. In IE, you're somewhat restricted by technical limitations.
Jonathan Fingland
I <3 inline block, just make sure to fix IE and FF2's non-support for it. display: -moz-inline-box for FF2, and switch your divs to spans for IE. IE can only render native inline elements with inline block. However, in this case I'd recommend the floating method by jonathan.
rpflo
Also, is there any way to have guaranteed static padding of say 1em as opposed to using percentage based padding/margins?
Nope. If you want a definite padding I'd put an element inside your DIVs and give it margin instead.
rpflo
neither this, nor the floating, method will work well with a mix of fixed margins and percentage sizes. when resizing the browser window, the fixed sizes don't change and the percentage ones obviously do. This leads to unintended line breaks and the like
Jonathan Fingland
+4  A: 

Table cells could stretch automatically. It's not exactly possible with div, so you have to specify appropriate width for each column by hand. For example:

#col1, #col2 {
    float: left;
    width: 50%;
}
esycat
Thank you esycat. I was tossing around the idea of using the CSS properties table-row and table-cell to mock the table like behavior, but I wasn't sure of the support for this, nor if it was a bad design methodology. This won't be used in the main structure of the site, just for displaying some pretty dynamic data. What do you think?
What's wrong with jonathan's code? If it's not working make sure you are accounting for left/right margin/padding/border on both elements, and if using those styles do them in percentages.
rpflo
I believe, using table-row/table-cell/etc is an abuse of CSS. Moreover, as far as I remember my last attempt to use these properties in such way, you will come to a quite cluttering mark-up to make all this work properly in all browsers.
esycat
see http://www.smashingmagazine.com/2007/05/01/css-float-theory-things-you-should-know/ for why you shouldn't use floats in this case
Jonathan Fingland
Using display: table and friends to make something display like a table is far from an abuse of CSS - the whole point of seperating structure and style is that you can do things like rendering data in a table like manor without claiming that the data is tabular. That said, it isn't supported by Internet Explorer 7 and earlier.
David Dorward
Sorry, but I'm wary about two things that take 50% each because float will decide to go on the next line if you specify margins or borders (since if you specified 1px margin, you'd have to set "width: 50%-2px" and you can't really do that) or the browser can theoretically mess it up by doing rounding errors.
ilya n.
A: 

My preferred solution

Use positioning relative to the outer container:

#container, #container > div  
{
    position: relative;
}

#col1  
{
     left: 2%; /* your margin */
}

#col2  
{
     right: 2%;
}

#container > div 
{
     width: 47%;
}

Note that you leave approximately the same 2% in the middle. The #col1 and #col2 should be aligned now.

Other solutions

With CSS3: use column-count: 2 and break column after first div.

If you really feel like floating, do only #col1 { float: left; width: 50%; }

ilya n.
A: 
#container{
overflow: hidden
} 

#col1, #col2 {
    float: left;
    width: 50%;
}
Rony