tags:

views:

105

answers:

6

I have a page generated by a database. It creates a DIV for each entry (extremely simplified for sake a question). Each of these DIVs have a set width, and float left.

However, these DIVs don't have a set height, so occasionally the following as depicted in the image happens. Is there a good way to prevent this from happening, and the white space just 'collapsing?'

The link to the prototype site. Here

A: 

Updated version of code which reproduces issue (not an answer):

<!DOCTYPE html>
<html lang="en">
<head>
    <style>
    .container
    {
     width:500px;
    }
    .box
    {
     float:left;
     width:200px;
     border:1px solid;
    }
    </style>
</head>
<body>
    <div class="container">
     <div class="box">Hi<br/>Hi<br/>Hi</div>
     <div class="box">Hi<br/>Hi<br/>Hi</div>
     <div class="box">Hi<br/>Hi<br/>Hi<br/>Hi</div>
     <div class="box">Hi<br/>Hi<br/>Hi</div>
     <div class="box">Hi<br/>Hi<br/>Hi</div>
     <div class="box">Hi<br/>Hi<br/>Hi</div>
    <div/>
</body>
</html>
Mark Byers
Edited my original post to show a link to the project.
Zack
+1  A: 

Depending on what you have control over, you could always add clear: left; to every other element in your 2-column scenario.

Though, I beleive that the second "The Postal Shoppe" would actually be on the left, and the Brynwood Pak N Ship would be in the right column.

The problem isn't so much that "Brynwood Pak N Ship" isn't collapsing the white-space, it's that the second "The Postal Shoppe" is getting hung up trying to move all the way to the left column by the bottom right corner of the "Express Pack & Mail Center."

Setting clear: left will ensure those entries always move down far enough to "suck up" to the left edge of their parent container. But you will still see some un-evenness using that attribute; the "Brynwood Pak N Ship" will line it's top up with the newly-cleared "Postal Shoppe" showing a tiny gap at the top. Still probably preferable to what's going on currently.

Pseudo Masochist
I don't think it is safe to assume that the objects will always appear in two columns if he is using "float:left". It will depend on the width of the browser window. Zack: is this correct?
Mark Byers
Actually, it will always display as two columns. The width of the container is fixed.
Zack
I don't mind unevenness if the whitespace is gone. I'm not a css pro, just a newb.
Zack
Yes, that's why I specifically called out the two column scenario. Adapting to n number of columns with i-entries should just be adding it to entry #(i mod n)==1.
Pseudo Masochist
Zack: The width of the container might be fixed, but the width of your user's browser window is not. Are you setting the width it to a percentage value or a number of pixels?
Mark Byers
Sorry Mark, I see what you're saying now... I was assuming a static width parent container.
Pseudo Masochist
Static Width. Set in Pixels.
Zack
OK, I understand now.
Mark Byers
+1  A: 

You can add a clear: left attribute to every other div. Alternately, you could try using display: inline-block instead of floating left, but it's not as widely supported (I think it breaks in IE 6 or older), so you'd have to see what hacks are out there to make it work universally.

keithjgrant
I tried `display:inline-block` in my example code and it still results in some gaps, although they seem to be typically smaller and less ugly.
Mark Byers
I tried it as well, and still seems to show gaps.
Zack
Ah, I see. it sounds like what you're really trying to do is 2 columns where order doesn't matter much and the divs don't need to align vertically with each other. Unfortunately, that's a bit trickier. You can create two divs, one for each column, but then you have to split your boxes so roughly half go in the left column, then the rest go in the right column.
keithjgrant
+1  A: 

I suggest giving every box an equal height. This is visually better, and it solves your problem in one go!

Exception e
+4  A: 

I think this article would help you: http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block/

Eugene
A: 

I think this is difficult to solve in CSS. I like the suggestions other users have made with 'display:inline-block' and setting the height to be fixed. They both have minor drawbacks, but the situation will be better than it currently is.

If you are going to solve this "properly", we first need to agree what the proper solution is. I think it would be to have two columns, and for each element that has to be added, it is appended to the end of the currently least-full column. This won't necessarily result in elements alternately being placed in column 1 then column 2. Sometimes two (or more) small elements will be placed in column 2 to compensate for a large element in column 1, for example.

I doubt something as complicated as this is possible to define in CSS (but I've been surprised by what can be done before). It could be done using Javascript though. You could have a solution that does a fairly good job if Javascript is disabled using a purely CSS solution, and if Javascript is enabled you could arrange them more elegantly.

I'm not sure it is worth the effort of implementing this though. Some of the existing suggestions seem reasonable compromises, and if it were me, I'd probably go with the inline-block solution, but I thought I'd throw this idea out anyway.

Mark Byers