views:

523

answers:

7

I'd like to line up items approximately like this:

item1      item2           i3           longitemname
i4         longitemname2   anotheritem  i5

Basically items of varying length arranged in a table like structure. The tricky part is the container for these can vary in size and I'd like to fit as many as I can in each row - in other words, I won't know beforehand how many items fit in a line, and if the page is resized the items should re-flow themselves to accommodate. Eg. initially 10 items could fit on each line, but on resize it could be reduced to 5.

I don't think I can use an html table since I don't know the number of columns (since I don't know how many will fit on a line). I can use css to float them, but since they're of varying size they won't line up.

So far the only thing I can think of is to use javascript to get the size of largest item, set the size of all items to that size, and float everything left.

Any better suggestions?

A: 

You could use block level elements floated left, but you will need some javascript to check the sizes, find the largest one, and set them all to that width.

EDIT: Just read the second half of your post, and saw that you suggested just this fix. Count this post as +1 for your current idea :)

Chris Marasti-Georg
A: 

You would actually need to calculate the maxWidth and the maxHeight and then go through with a resize function in Javascript after the page loads. I had to do this for a prior project and one of the browsers (FF?) will snag/offset the ones underneath if the height of the divs vary.

A: 

Well, could you just create a floated div for each 'item', and loop through its properties and use linebreaks? Then when you finish looping over the properties, close the div and start a new one? That way they will be like columns and just float next to each other. If the window is small, they'll drop down to the next 'line' and when resized, will float back up to the right (which is really the left :-)

EvilSyn
A: 

You could float a couple of unordered lists, like this:

<ul style="float: left;">
    <li>Short</li>
    <li>Loooong</li>
    <li>Even longer</li>
</ul>
<ul style="float: left;">
    <li>Loooong</li>
    <li>Short</li>
    <li>...</li>
</ul>
<ul style="float: left;">
    <li>Semi long</li>
    <li>...</li>
    <li>Short</li>
</ul>

It would require you to do some calculations on how many list-items in how many lists should be shoved into the DOM, but this way - when you re-size the container which holds the lists - the lists will float to fit into that container.

roosteronacid
But I won't know how many items to put into each ul.
Parand
Then I think you should use a table. That is - after all - what tables are for. But I take it there's a good argument for not doing exactly that? :)
roosteronacid
In any case: be pragmatic. If it works cross-browser, then it works. If something breaks, or the code you've written becomes too slow, THEN performance-tune and and fix.Ever heard the motto "launch crap, but launch"? I swear by it (with some exceptions, of course - this case not being one of em).
roosteronacid
... Since you seem to have come up with a solution, although not so pretty.
roosteronacid
+2  A: 

This can be done using floated div's, calculating the max width, and setting all widths to the max. Here's jquery code to do it:

html:

<div class="item">something</div>
<div class="item">something else</div>

css:

div.item { float: left; }

jquery:

var max_width=0;
$('div.item').each( function() { if ($(this).width() > max_width) { max_width=$(this).width(); } } ).width(max_width);

Not too ugly but not too pretty either, I'm still open to better suggestions...

Parand
+1  A: 

What happens when you get one item thats rediculously large and makes the rest look small? I would consider two solutions:

  1. What you've already come up with involving a float:left; rule and jQuery, but with a max max_width as well or
  2. Just decide on a preset width for all items before hand, based on what values you expect to be in there

Then add an overflow:hidden; rule so items that are longer don't scew the table-look. You could even change the jQuery function to trim items that are longer, adding an elipsis (...) to the end.

roryf
A: 

You could use the following with each column the same width.

You'll have a fixed column width, but the list will reflow itself automatically. I added a little bit of extra HTML but now it works in FF en IE.

html:

<ul class="ColumnBasedList">
  <li><span>Item1 2</span></li>
  <li><span>Item2 3</span></li>
  <li><span>Item3 5</span></li>
  <li><span>Item4 6</span></li>
  <li><span>Item5 7</span></li>
  <li><span>Item6 8</span></li>
</ul>

css:

.ColumnBasedList
{
    width: 80%;
    margin: 0;
    padding: 0;
}

.ColumnBasedList li
{
    list-style-type: none;
    display:inline;
}

.ColumnBasedList li span
{
    display: -moz-inline-block;
    display: inline-block;
    width: 20em;
    margin: 0.3em;
}
Davy Landman
This one is not working for me - it shows up as just a simple list, no reflowing (FF 2.x).
Parand
display: inline-block; should be display: inline;
defrex
no... its only supported in ff3. and besides, hes setting a fixed width so it doesnt work. this is pretty much just a table.
Shawn Simon
Correct, I changed my answer to make it cross browser.
Davy Landman