There are a lot of legitimate reasons not to use tables for layout - it’s not semantic in most cases, people start slapping them around elements for no good reason, etc, etc, etc…
But there are a lot of myths propagated by the die-hard anti-table mafioso zealots. One of these myths has reared it’s ugly head in this thread.
… and both of those quotes play to the first myth - bandwidth. Properly written tables styled with CSS is usually about the same in terms of filesizes - or even smaller in many cases than other techniques like “endless nested div” or “list abuse” (see some of the **** forum themes lately abusing lists and cloaked content on obviously tabular data)
If properly written it’s the same size or smaller - it’s not less bandwidth and therein not faster - Now you COULD be talking about rendering speed; tables do render slower and often hang the rendering until the HTML is completely loaded… but if a 386/40 running Windows 3.1 could handle a table, that part of the arguement is also total nonsense in the age of multi-ghz multi-core computers.
A great example of this abuse can be found in the vBulletin 4 skins. Apologies to Digital Point for crapping on their codebase, but for example take a topic index (forumdisplay.php) on the new skins… This is OBVIOUSLY tabular data; or at least data that should be presented in a tabular format. Icon, title, Starter, Replies, Views, Last Post - columns with proper headings all - that’s TABULAR DATA… so what does vBULL 4 do? Let’s pull the header and the first item row.
<div id="threadlist" class="threadlist">
<form id="thread_inlinemod_form" action="inlinemod.php?forumid=39" method="post">
<h2 class="hidden">Threads in This Forum</h2>
<div>
<div class="threadlisthead table">
<div>
<span class="threadinfo">
<span class="threadtitle">
<a href="forumdisplay.php?f=39&sort=title&order=asc" rel="nofollow">Title</a> /
<a href="forumdisplay.php?f=39&sort=postusername&order=asc" rel="nofollow">Thread Starter</a>
</span>
</span>
<span class="threadstats td"><a href="forumdisplay.php?f=39&sort=replycount&order=desc" rel="nofollow">Replies</a> / <a href="forumdisplay.php?f=39&sort=views&order=desc" rel="nofollow">Views</a></span>
<span class="threadlastpost td"><a href="forumdisplay.php?f=39&sort=lastpost&order=asc" rel="nofollow">Last Post By<img class="sortarrow" src="http://b.dpstatic.com/buttons/sortarrow-white-asc.png" alt="Reverse Sort Order" border="0" /> </a></span>
</div>
</div>
<ol id="threads" class="threads">
<li class="threadbit new" id="thread_1785204">
<div class="rating0 nonsticky">
<div class="threadinfo">
<!-- status icon block -->
<a class="threadstatus" rel="vB::AJAX" ></a>
<!-- title / author block -->
<div class="inner">
<h3 class="threadtitle">
<a href="showthread.php?t=1785204&goto=newpost" id="thread_gotonew_1785204"><img class="gotonewpost" src="http://b.dpstatic.com/buttons/firstnew.png" alt="Go to first new post" /></a>
<a class="title threadtitle_new" href="showthread.php?t=1785204" id="thread_title_1785204">Center container DIV vertically</a><span class="age one">1</span>
</h3>
<div class="threadmeta">
<p class="threaddesc">Hi.
I know how to center it horizontally, with margin:0 auto, but how do you also center it vertically?</p>
<div class="author">
<span class="label"><a href="member.php?u=407651" class="username understate" title="Started on Yesterday 9:24 am">Abh</a></span>
</div>
</div>
</div>
<!-- iconinfo -->
<div class="threaddetails td">
<div class="threaddetailicons">
</div>
</div>
</div>
<!-- threadstats -->
<ul class="threadstats td alt" title="">
<li>Replies: <a href="misc.php?do=whoposted&t=1785204" onclick="who(1785204); return false;" class="understate">4</a></li>
<li>Views: 48</li>
<li class="hidden">Rating0 / 5</li>
</ul>
<!-- lastpost -->
<dl class="threadlastpost td">
<dt class="lastpostby hidden">Last Post By</dt>
<dd><div class="popupmenu memberaction">
<a class="username offline popupctrl" href="member.php?u=407651" title="Abh is offline"><strong>Abh</strong></a>
<ul class="popupbody popuphover memberaction_body">
<li class="left">
<img src="http://i.dpstatic.com/site_icons/profile.png" alt="" />
<a href="member.php?u=407651">
View Profile
</a>
</li>
<li class="right">
<img src="http://i.dpstatic.com/site_icons/forum.png" alt="" />
<a href="search.php?do=finduser&userid=407651&contenttype=vBForum_Post&showposts=1" rel='nofollow'>
View Forum Posts
</a>
</li>
<li class="right">
<img src="http://i.dpstatic.com/site_icons/blog.png" alt="" />
<a href="http://blogs.digitalpoint.com/?u=407651" rel='nofollow'>
View Blog Entries
</a>
</li>
<li class="left">
<img src="http://i.dpstatic.com/site_icons/homepage.png" alt="" />
<a href="http://romanga.5com.ro/" rel="nofollow">
Visit Homepage
</a>
</li>
<li class="right">
<img src="http://i.dpstatic.com/site_icons/article.png" alt="" />
<a href="http://articles.digitalpoint.com/list.php/author/407651-Abh" rel='nofollow'>
View Articles
</a>
</li>
<li class="left">
<img src="http://i.dpstatic.com/site_icons/add.png" alt="" />
<a href="profile.php?do=addlist&userlist=buddy&u=407651">
Add as Contact
</a>
</li>
</ul>
</div>
</dd>
<dd>Today <em class="time">11:27 am</em> <a href="showthread.php?t=1785204&page=#post14112029" class="lastpostdate understate" title="Go to last post"><img src="http://b.dpstatic.com/buttons/lastpost-right.png" alt="Go to last post" /></a></dd>
</dl>
</div>
</li>
4.5k of markup for 200 bytes of content visible to the user and a handful of links?!? Abusing ordered lists, abusing definition lists by only having DD’s in it? Cloaking content, redundant titles in the text? Even if we axe that stupid malfing javascripted for no good reason menu rubbish under last post, it’s still over 3k doing the job of:
<table class="topicList">
<thead>
<tr>
<th class="description">
<a href="forumdisplay.php?f=39&sort=title&order=asc" rel="nofollow">Title</a>
</th>
<th class="startedBy">
<a href="forumdisplay.php?f=39&sort=postusername&order=asc" rel="nofollow">Thread Starter</a>
</th>
<th class="count">
<a href="forumdisplay.php?f=39&sort=replycount&order=desc" rel="nofollow">Replies</a>
</th>
<th class="count">
<a href="forumdisplay.php?f=39&sort=views&order=desc" rel="nofollow">Views</a>
</th>
<th class="lastPost">
<a href="forumdisplay.php?f=39&sort=lastpost&order=asc" rel="nofollow" class="asc">Last Post By</a>
</th>
</tr>
</thead><tbody>
<tr id="post_1785204">
<td class="description">
<h2>
<a href="showthread.php?t=1785204&goto=newpost"
title="Hi. I know how to center it horizontally, with margin:0 auto, but how do you also center it vertically?"
>
<img src="http://b.dpstatic.com/buttons/firstnew.png" alt="Go to first new post" />
</a>
<a href="showthread.php?t=1785204">
Center container DIV vertically
</a>
</h2>
- 1 day old
</td>
<td class="startedBy">
<a href="member.php?u=407651" title="Started on Yesterday 9:24 am">Abh</a>
</td>
<td class="count">4</td>
<td class="count">48</td>
<td class="lastPost">
<a href="showthread.php?t=1785204&page=#post14112029">Today at <span>11:27 am</span></a><br />
by <a href="member.php?u=407651" title="Abh is offline">Abh</a>
</td>
</tr>
Comes out to 1.6k - Even if you put all that scripted asshattery back in, using tables BECAUSE semantically it’s tabular data (aka the rows are related, and the columns are related) I very much doubt it would break 2.5k… Not only is it a great example of the anti-table whacko’s taking the concept WAY too far, it’s a great example of javascripting application type features that the majority of users aren’t going to use and is little more than a bandwidth hogging pig.
A recently departed friend was fond of saying “The people who used to make fat bloated nested tables now just make fat bloated nested DIV” - as much as I hate to correct Dan, it’s gotten a lot worse than that with people abusing tags for **** they just don’t mean!
Much of the problems with tables have NOTHING to do with tables at all, and quite frankly not using tables doesn’t fix the underlying problem of people just slapping tags in there any old way. The problem lay in that the majority of developers didn’t know enough about coding tables to be using them in the first place? TH? CAPTION? THEAD? TBODY? If you’ve never heard of those, you are part of the problem.
You’ll see developers vomiting up code like this all the damned time:
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="tBorder">
<tr>
<td colspan="4" class="bigtext"><h2>CSS Forum</h2></td>
</tr><tr>
<td class="heading fullw"><strong>Title</strong></td>
<td class="heading shr"><strong>Replies</strong></td>
<td class="heading shr"><strong>Views</strong></td>
<td class="heading w15"><strong>Last Post</strong></td>
</tr><tr>
<td class="data trow1">
<span class="bigText"><a href="index.php?t=1">Some Topic</a></span>
</td>
<td class="data trow1"><span class="smalltext">4</span></td>
<td class="data trow1"><span class="smalltext">48</span></td>
<td class="data trow1"><span class="smalltext">
Last Post by somebodyorother
</span></td>
</tr><tr>
<td class="data trow2">
<span class="bigText"><a href="index.php?t=2">Some Topic</a></span>
</td>
<td class="data trow2"><span class="smalltext">4</span></td>
<td class="data trow2"><span class="smalltext">48</span></td>
<td class="data trow2"><span class="smalltext">
Last Post by somebodyorother
</span></td>
</tr>
</table>
What’s wrong with that you ask? We have CSS, you don’t need to set cell properties in the markup anymore, that’s border-collapse’s job. If every one of your elements in a parent container are all getting the same class, they don’t need a class on them style off the PARENT. <td class=“heading”><strong> OH HELL NO. Every time I see that I want to *****-slap whoever wrote it - see, that’s what TH is for! colspan bigtext? No, that’s a CAPTION… and NEWS FLASH, you use those tags, screen readers will have a LOT less headaches dealing with your code. It’s made worse by vague/meaningless classnames like “shr”, “w15” - what the hell do those even MEAN!?! Presentational classnames don’t help a whole lot either, helps to say WHAT things are, NOT what styling you are applying to them. Classnames that say what style you are applying like “bigtext”, “smalltext” or even “tborder” are so pointless they beg the question “Ok, what are you even bothering to use CSS for at that point?!?” - we can dissect this bull even further by pointing out that the classes applied to the span could just as easily have been tacked onto the parent TD, negating the need for all of those too!
That is an absolute train wreck of code but you see people coding this way all the **** time. Not only does it mean the coder was unaware of CAPTION, THEAD, TBODY, TH, etc, etc… they failed to grasp the fundementals of how HTML/CSS even works… especially the ‘cascading’ part of CSS.
See, there’s no reason for that to be anything more than:
<table class="postList">
<caption>CSS Forum</caption>
<thead>
<tr>
<th class="title">Title</th>
<th class="replies">Replies</th>
<th class="views">Views</th>
<th class="lastPost">Last Post</th>
</tr>
</thead><tbody>
<tr class="odd">
<th class="title">
<a href="index.php?t=1">Some Topic</a>
</th>
<td class="replies">4</td>
<td class="views">48</td>
<td class="lastPost">Last Post by somebodyorother</td>
</tr>
<tr class="even">
<th class="title">
<a href="index.php?t=1">Some Topic</a>
</th>
<td class="replies">4</td>
<td class="views">48</td>
<td class="lastPost">Last Post by somebodyorother</td>
</tr>
</tbody>
</table>
A fraction the code, functionally identical once you get CSS in the mix… actually not true, the use of headings and captions means screen readers won’t choke on it, and will associate the column headings (thead th) with the table-cells below them in body… and the th.title in tbody will end up associated with their rows. (Oh, and all of those td/th classes could be gotten rid of if IE supported nth-child or sibling selectors properly or if Firefox/Gecktard supported colgroups correctly - see TWELVE YEAR OLD bugzilla 915)
That’s called using a table properly, and I believe the number of people who do it can be counted on one hand.
But there are legitimate reasons NOT to use tables - three columns of unrelated content is NOT tabular data. Wrapping single elements in tables just for centering or spanning effects is a waste of bandwidth… I have a list of excusable reasons for using tables:
-
Obviously tabular data where you are going to have headings over your columns where the columns are all the same type of information, and the rows are all related records.
-
Vertical positioning effects that CSS just cannot do. (like content you cannot predict the height of)
-
When faux columns just won’t cut it.
… and that’s it. Conversely there are some simple rules as to when a table is completly inappropriate…
-
just to center something horizontally
-
if you are only going to have one TD or a single column of TD
-
When every TD is the exact same information with no vertical column type relationships. (image galleries for example)
-
when your columns are simply columns, not multiple rows of related data.
It’s pretty simple, it only gets complex when people start MAKING it more complex than neccessary. That’s a REALLY short inappropriate list, but 90%+ of the tables in use out there fall into one if not ALL of those categories.
Sorry for the long post - it’s what I do.