tags:

views:

58

answers:

3

Hi,

I'm creating templates for a Django project, and I need to create a three column table in HTML, using just CSS, rather than a <table> element.

The reason, apart from any ideological opposition to tables, is that the report needs to be viewed on both desktops as well as handheld devices such as BlackBerry. On handhelds, rather than trying to force three columsn on a minuscule screen, the objective is to break up the table into a series of consecutive paragraphs.

Previously, I'd hacked a quick/dirty template out using the Less framework (http://lessframework.com/).

            {% for category in article_list_categorised %}
                    <h2 class="first">{{ category.grouper }}</h2>
                            {% for item in category.list %}
                                    <h3 class="two first">{{ item.firms.all|join:", " }}</h3>
                                    <h4 class="two">{{ item.subject }}</h4>
                                    <p class="seven">
                                            {{ item.abstract }}
                                    </p>
                                    <h4 class="one">{{ item.source_publication }}</h4>
                                    <h4 class="one">{{ item.publication_date }}</h4>
                                    <h4 class="one">Page: {{ item.page_number }}</h4>
                            {% endfor %}
            {% endfor %}

            <footer>
                    <p class="four off-four">
                            {% now "l, jS F Y" %}
                    </p>
            </footer>

On screen, this gives a three column table, containing a list of articles. For each article (row), we have:

  1. First column contains the firm name
  2. Second column contains the subject and article abstract
  3. Third column contains the source publication, the publication date and the page number.

And when displayed on the BlackbBerry browser, it breaks up the columns in consecutive paragraphs, on top of each other.

Now, I want to move away from using Less to doing the markup/CSS from scratch.

I found another StackOverflow question asking something similar:

http://stackoverflow.com/questions/3473043/how-to-create-three-columns-in-css

and the advice from there is basically to use <ul> and <li>. I've hacked out something like this, two rows, three columns:

        <ul>
            <li> <!-- First row -->
                <ul>
                    <li>Deutsche Bank, Goldman Sachs JBWere</li>
                    <li>Costs</li>
                    <li>
                        <p>AAP</p>
                        <p>June 28, 2010</p>
                        <p>Page: 3</p>
                    </li>
                </ul>
            </li> <!-- End of first row -->
            <li> <!-- Second row -->
                <ul>
                    <li>Deutsche Bank</li>
                    <li>Plans</li>
                    <li>
                        <p>Bloomberg</p>
                        <p>June 29, 2010</p>
                        <p>Page: 1</p>
                    </li>
                </ul>
            </li> <!-- End of Second row -->
        </ul>

My question is, is this optimal, or is there perhaps a more streamlined hierarchy I could go for, or any tags I can strip out of the above?

Also, the article referenced in the above question talks about three columns, with one row. I need three columns, with a new row for each article.

What's a good way of CSS styling the above, to give three columns, with each set on a new row, and still have it display as consecutive paragraphs on handhelds?

Cheers, Victor

A: 

I'd go for 3 divs, each containing one column, give them a min-width and a max-width, and display: inline-block. If the screen is large enough to accommodate them next to each other, they'll be laid out as 3 columns, otherwise, they'll stack. You'll need some extra hacks for IE 6 (maybe 7 too) because it doesn't support inline-block.

tdammers
+1  A: 

Using an unordered list is not a BAD method, and the benefit of this is that devices or browsers with CSS disabled (yep, you'll be surprised) will degrade gracefully into a legible list. If you wanted the above to display in a 3 column layout with each row on a new "line" I would try something like this for your css:

First give your ul an ID attribute, so in our case we'll call it <ul id="fakeTable">, and then we can style our li elements to act as table cells:

#fakeTable, #faketable li{
  list-style-type:none; //no bullets etc
  margin:0;
  padding:0;
  }

#fakeTable{
  width:800px; //you could set it to any width really, just an example
  }

#fakeTable li{
  display:block;
  float:left;
  clear:none;
  width:200px;
  padding:0 11px 0 11px;
  }
  • Now assuming your <ul> is 800px wide, the <li> elements will wrap to the next line from 4 to 6, 7 to 9 etc as there is no more space to float a 4th one on each row.

  • If you do not have a set width, convert the widths to %, you could have the <li> width set to 33% - with no <li> padding of course - which will give you a width of 99% across 3 <li> elements, so no space for a 4th, and it will wrap to the next line!

webfac
That being said, floating 3 divs next to each other is as effective, but on screen devices you can be assured that the ul li approach will be a lot more legible when and if it breaks. Also, DIVS can do funny things when floated, especially when they vary in height. They can wrap in all sorts of ways that will render your content difficult to read.
webfac
@webfac: I think it's awesome that you're approach still uses <li>/<ul>. However, what I actually need is the data to appear in rows. So for example, the sample code in the question would produce two rows - in the first row, column one, you'd have "Deutsche Bank, Goldman Sachs JBWere", second column would have "Costs", and third column would have "AAP...Page: 3". Then on row two, first column, we have "Deutsche Bank", row two, second column "Plans", and so on. Is something like that possible?
victorhooi
@victorhooi - Same concept could apply, simply make each li element 100% wide, clear both sides, that will take care of your rows. Then inside each <li> element you could have two divs, lets say .col1 and .col2, and each div will be 50% wide (or whatever you wish) and float .col1 left with clear:none and float .col2 left with clear:none or float it right, don't really matter in this case if they 50% wide each. Make sense?
webfac
A: 

Create multi-column layout with div is very simple but you should pay attention to the followings:

  • Sum of width of element column (including margin and padding) must < 100% (or width of the main column in pixel).
  • Using float:left (or right) to ensure the column appear side-by-side
  • Using a clear element to ensure the margin attribute of below elements

Example:

  <div id="main">
    <div class="col 1st-col">
    </div>
    <div class="col 2nd-col">
    </div>
    ...
    <div class="clr"></div>
  </div>

.col {float: left;} .1st-col {width: 30%; margin-left: 1%} ....

.clr {background: url('empty.gif');} /* empty.gif is a gif image (1px x 1px transparent) */

This surely works on every browser. Div .clr to fix the height of div.main in FF, Chrome, IE6. The attribute display: inline-block doesn't work in IE.