4

I have about a hundred short-text data items (this number can vary substantially) that I would like to put in a page and have the browser manage that into three columns within a surrounding div, arranged with the items going down and then across, like this:

A    F    L
B    G    M
C    H    N
D    I    O
E    K    ...

Is there a way to render this out as li's (or maybe just individual lines), and have the browser automatically collate it into three equal-height columns, possibly using CSS?

Are there any browser compatibility issues?

2
  • 1
    You mentioned "browser". I think pure css is not possible to do so. But you certainly can do it javascript. Are you also looking for options in javascript? Commented Jul 21, 2009 at 3:08
  • Sure, I'm open to Javascript. Commented Jul 21, 2009 at 3:12

6 Answers 6

9

Without browser compatibility issues:

<% var rows = source.Count() % 3 == 0 ? source.Count / 3 : (source.Count / 3) + 1; %>
<table>
    <% for(int i=0; i<rows; i++) { %>
    <tr>
        <td><%= source.Skip(i).FirstOrDefault() %></td>
        <td><%= source.Skip(i+rows).FirstOrDefault() %></td>
        <td><%= source.Skip(i+rows*2).FirstOrDefault() %></td>
    </tr>
    <% } %>
</table>

We use the modulus operator to let us know if the division is even or not... if it is not, we're not going to add an extra row for the leftover columns. For more information, see http://msdn.microsoft.com/en-us/library/0w4e0fzs.aspx

For example look at https://stackoverflow.com/users HTML source - it uses <table>

Sign up to request clarification or add additional context in comments.

2 Comments

I think if you're not adverse to this solution it is probably the most preferable. Your resulting code will be far more efficient than having to process it client side with javascript.
This is really elegant. Candidate for the correct answer, although I did find a client-side solution, which I will post shortly.
2

In the CSS world this is the only way I know to do three columns outside of a table of course.

<html>
    <div style="width:100px">
        <div style="float:left; width:33%;">a</div>
        <div style="float:left; width:33%;">bsdf</div>
        <div style="float:left; width:33%;">c</div>
        <div style="float:left; width:33%;">d</div>
        <div style="float:left; width:33%;">e</div>
        <div style="float:left; width:33%;">f</div>
        <div style="float:left; width:33%;">g</div>
    </div>
</html>

Clearly you wouldn't use all those style tags, instead you'd use an actual style. Notice the 33% as the width.

I tried this in IE and FirFox and no probs on either.

4 Comments

I also tried setting the width of the parent to 500px and the whole thing remained as three columns.
Mmm, no good. It makes three columns, but it collates left to right first. I need it to collate top to bottom first.
Isn't that just the order in which you place the inner divs? I'm pretty sure, and my css isn't expert level, that what you're asking to do is not do-able. Though now someone out there is bound to prove me wrong.
if you are okay with the order in which the elements are laid down then this is a good clean solution.
2

After Xandy suggested Javascript, I did some googling for jQuery plugins, and found this:

Newspaper Columns JQuery Plugin
http://www.webmeisterei.com/petznick/2007/05/16/newspaper-columns-jquery-plugin/

Usage:
You need a Container with Elements like

<div id="npContainer">
  <div class="npItem">Item1</div>
  <div class="npItem">Item2</div>
</div>

...and you need the Columns

<div id="npColumn1"></div>
<div id="npColumn2"></div>
<div id="npColumn3"></div>

In Javascript just call:

jQuery().npColumns();

A web page that uses the plugin
http://www.bregenzerwald-news.at/?classifieds=1

Comments

1
<div style="float: left">A</div>
<div style="float: left">B</div>
<div style="float: left">C</div>
<div style="float: left">D</div>
<div style="float: left">...</div>

Then place these into a div that has its width correctly set.

6 Comments

What about the height of the outer div? Will that manage itself?
How does it know it's supposed to be three columns?
Yeah should do. I don't ever recall having to set the height. The issue you may have is with the content and widths. eg: if you have columns a,b,c then another row of, horndrolic,e,f then you'll have odd columns. So set the width of each of the column divs. obviously do this in a style tag. :)
It doesn't know about columns. See above comment.
OK. Thanks for the tip, but I'm going to need something that's a little more column aware.
|
1

html can be (actually doesnt really matters):

<div class="3col_vert">
    <div>a</div>
    <div>b</div>
    <div>c</div>
    <div>d</div>
    ...
</div>

In javascripts (example in jquery in particular), you have to wrap them with cols, so that the resulting html (after manipulation of javascript) will become:

<div class="3col_vert">
    <div class="col_left">
        <div>a</div> ...
    </div>
    <div class="col_centre">
        <div>e</div> ...
    </div>
    <div class="col_right">
        <div>g</div> ...
    </div>
</div>

Jquery to mainpulate will be:

var vert_divs = $(".3col_vert div");
// Remove them from parent
$(".3col_vert").empty()
    .append("<div class='col_left'></div>") // append the wrapper cols to parent
    .append("<div class='col_center'></div>")
    .append("<div class='col_right'></div>");

// Now place them to the wrappers
var totalDivs = vert_divs.length; // count number of match divs

vert_divs.each(function(i) {
    if (i < totalDivs / 3)
        $(this).appendTo(".3col_vert div.col_left");
    else if (i<totalDivs * 2/3)
        $(this).appendTo(".3col_vert div.col_center");
    else
        $(this).appendTo(".3col_vert div.col_right");
});

The code above isn't too optimised ( I am sure lots of better algorithm can do), but the idea is there, you use javascript to manipulate the html into something like the above one, by putting the first 1/3 to left column, second 1/3 to center, and the rest to right. The last job is use CSS to make them into 3 columns, which I am not going to cover here but there's tons of tutorials out there, for instance, this one is one of those examples.

3 Comments

Exactly what I was starting to write up when I saw this answer, as long as the user is familiar with jQuery it will work very well.
Before meeting jquery, I don't write client script much, javascript programming is like tackling browser difference rather than productivity. BTW, if anyone is familiar with other framework or just implement in javascript, that's still fine, as it only manipulate the markup to "help" css do its job.
Thanks, xandy. See also my new post below.
1

You can't do this in CSS alone - though @griegs has shown how to do across then down.

If you always want 3 columns this should be easy with a little server side code and CSS - basically for each item you write something like:

<li>item</li>

Then at count/3 and count*2/3 add:

</ul><ul>

So you end up with something like:

<style>
    .three-column-panel > ul { 
        float:left; width:33%; list-style-type: none; text-indent:0; }
</style>    

<div class="three-column-panel">
    <ul>
        <li>a</li>
        <li>b</li>
        <li>c</li>
    </ul>
    <ul>
        <li>d</li>
        <li>e</li>
        <li>f</li>
    </ul>
    <ul>
        <li>g</li>
        <li>h</li>
    </ul>
</div>

1 Comment

I like the idea of handling the column height server-side. It might be worth writing an HTMLHelper Extension Method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.