I first became a front-end web developer in the year of our Lord, 1998. Back then, the HTML specification had just reached version 4.0; Internet Explorer 7 was the dominant browser; and, the mantra of separation-of-concerns was still being preached to web developers. (Back then merely uttering the phrase CSS-in-JS would've gotten you killed, professionally speaking.) What's more, back then, HTML tables were still de rigueur; in fact, many websites used them for layout purposes (DIV-itis hadn't caught on with the masses as yet; that would happen several years later.)
Yes, it was the stone ages of the web -- in comparison to today. Today, there's a wealth of newer technologies for developers to choose from when building websites, i.e. HTML5, CSS4, ES9, etc. Long gone is the mantra of separation-of-concerns and in its place sits CSS-in-JS, mockingly. And, long gone are table-based layouts too; they gave way to the aforementioned DIV-itis phenomenon and the later rise of responsive/adaptive designs. But let's forget about all of that for a moment... Haven't you ever wondered why tables were relegated to the dustbin of time -- only to be used for tabular data and nothing else! Was that because tables had major technical or functional flaws; or, was it simply a case of out with the old and in with the new? Well, I've often wondered about that; and, I've come to the conclusion that the answer has more to do with the latter case than anything else.
But rather than rehashing the arguments for and against using tables for layout (see this thread on StackOverflow if that's what you're looking for), I want to take a more productive approach to things by instead exploring whether tables could still, in fact, be used for layouts today. Specifically, could a table be used as the ideal container for a mobile-first, responsive/adaptive website -- especially when coupled with the power of CSS4 and perhaps even ES9? In this post, I intend to show that tables can, in fact, fit the bill -- all be it with several caveats.
Before I begin, I want to first acknowledge the risks associated with using tables for a website's layout. There's a real risk of developers creating heavily nested tables, as was the case in the past. This can lead to unmaintainable and poorly performing code. So, let's limit the number of tables to just one to mitigate this risk. Another risk is that table-based layouts could significantly degrade the browsing experience for people with disabilities. This is a serious concern for anyone who cares about accessibility; but again, I think this risk could be mitigated by setting up ARIA Roles on the table. Lastly, there's a semantic argument against using a table for a website's layout. I don't have a good counter-point to that argument, suffice to say that the table should be viewed as simply a container for other semantic tags like NAV, HEADER, FOOTER, etc.; and, that it's ironic that large swaths of the front-end community now embraces CSS-in-JS but decry using tables for layout on semantic grounds.
Having said all that, let's begin. Our goal is simple, i.e. to re-create the holy grail layout, which is basically a 3x3 grid (see figure below). Note that a particular website's "holy grail layout" could end up having many more rows and columns; however, it should only have one table.
![]() |
Holy grail Layout with Dropping Footer |
The HTML code to render a "holy grail layout" as a table is as follows:
Similarly, the HTML code to render the same layout as a series of DIVs is as follows:
Clearly, the latter block of code is much less than the former. However, once you begin to factor in the large amount of CSS that's needed in order to add structure to the DIV example, it begins to equal the TABLE's block of code. Regardless, there are other benefits to the TABLE block that I believe far outweigh the DIV block. For starters, the table-based approach comes with built-in responsiveness for desktop and tablet devices, with only a few minor CSS tweaks for mobile devices. What's more, the TABLE block comes with built-in support for source order; that is, the THEAD, TBODY, and TFOOT tags can be placed in any arbitrary order within the markup -- in order to improve Search Engine Optimization (SEO), for example -- yet still be rendered properly by browsers from a display perspective. Lastly, with the BORDER property of the TABLE set to "1" and its column WIDTHs specified, end-users are able to get a better sense of the orientation of the content on the screen and thus visually ground themselves. This is a huge win when you consider the fact that we haven't even introduced any CSS4 or ES9 code into the HTML markup for the TABLE as yet.
In case you're wondering, the CSS for the table-based approach looks as follows:
Note that these styles are primarily to make the TABLE responsive on mobile devices. That's accomplished by resetting the TABLE's DISPLAY property, which has the added benefit of also re-ordering the source. For example, by setting the display of the ".page .body .column" class to "table-footer-group", we've re-ordered the CONTENT section to visually appear before the AD and MENU sections
Now I'll grant you that this example might be a bit too simplified/contrived vs. real-world applications; but, it nonetheless clearly showcases some of the benefits of table-based layouts to non-table-based ones. So, should you start using tables in spite of CSS Grid and other such things? Not necessarily; it all depends on whether you value an HTML-first approach to development vs. a CSS or mobile-first one. Perhaps there's a middle ground to be found between the two approaches.
HTML TABLE MARKUP | RENDERED TABLE OUTPUT |
---|---|
cellspacing="0" border="1" width="100%" align="center"> <tbody class="body"> <tr class="row"> <td class="column menu" width="25%">MENU</td> <td class="column content" width="50%">CONTENT</td> <td class="column ad" width="25%">AD</td> </tr> </tbody> <tfoot class="foot"> <tr class="row"> <td class="column footer" colspan="3">FOOTER</td> </tr> </tfoot> <thead class="head"> <tr class="row"> <th class="column header" align="left" colspan="3">HEADER</th> </tr> </thead> </table> |
|
Similarly, the HTML code to render the same layout as a series of DIVs is as follows:
HTML DIV MARKUP | RENDERED DIV OUTPUT |
---|---|
<div class="page"> <main class="body row"> <div class="column menu">MENU</div> <div class="column content">CONTENT</div> <div class="column ad">AD</div> </main> <footer class="foot row"> <div class="column footer">FOOTER</div> </footer> <header class="head row"> <div class="column footer">HEADER</div> </header> </div> |
|
Clearly, the latter block of code is much less than the former. However, once you begin to factor in the large amount of CSS that's needed in order to add structure to the DIV example, it begins to equal the TABLE's block of code. Regardless, there are other benefits to the TABLE block that I believe far outweigh the DIV block. For starters, the table-based approach comes with built-in responsiveness for desktop and tablet devices, with only a few minor CSS tweaks for mobile devices. What's more, the TABLE block comes with built-in support for source order; that is, the THEAD, TBODY, and TFOOT tags can be placed in any arbitrary order within the markup -- in order to improve Search Engine Optimization (SEO), for example -- yet still be rendered properly by browsers from a display perspective. Lastly, with the BORDER property of the TABLE set to "1" and its column WIDTHs specified, end-users are able to get a better sense of the orientation of the content on the screen and thus visually ground themselves. This is a huge win when you consider the fact that we haven't even introduced any CSS4 or ES9 code into the HTML markup for the TABLE as yet.
In case you're wondering, the CSS for the table-based approach looks as follows:
CSS TABLE STYLES | RENDERED TABLE OUTPUT ON MOBILE DEVICE |
---|---|
.page { max-width: 1200px; } .page .column { vertical-align: top; } @media only screen and (max-width: 638px) { .page .head .column { display: table-header-group; } .page .body .column { display: table-footer-group; } .page .foot .column { display: block; } } |
|
Note that these styles are primarily to make the TABLE responsive on mobile devices. That's accomplished by resetting the TABLE's DISPLAY property, which has the added benefit of also re-ordering the source. For example, by setting the display of the ".page .body .column" class to "table-footer-group", we've re-ordered the CONTENT section to visually appear before the AD and MENU sections
Now I'll grant you that this example might be a bit too simplified/contrived vs. real-world applications; but, it nonetheless clearly showcases some of the benefits of table-based layouts to non-table-based ones. So, should you start using tables in spite of CSS Grid and other such things? Not necessarily; it all depends on whether you value an HTML-first approach to development vs. a CSS or mobile-first one. Perhaps there's a middle ground to be found between the two approaches.
Comments
Post a Comment