Never Use HTML Tables, Ever!

I know what you’re probably thinking, come on man…there are legitimate reasons for using tables on occasion, to display tabular data, etc.  Well, yes and no.  Agreed, there is the need for table like formatting and functionality however, tables bring with them some very bizarre remnants with regard to CSS, JavaScript interaction (especially with adding and removing rows, try a google search, you’ll see what I’m talking about) as well as a few other unmentionables used by a few ambitious developers out there.  So what do we do, never use them again…ever!  “What?  Wha…what is this nonsense you speak of?” one might say and here’s my answer.

We don’t need to use tables, we can get table like functionality cleanly with none of the hassles of using true HTML tables especially with regard to JavaScript and CSS, and here’s how.

Replace all HTML tables with CSS styled equivalents.  Let’s take a look at a properly formatted HTML table, then we’ll look at how to replace it.  Consider the following:

            <th>Heading 1</th>
            <th>Heading 2</th>
            <th>Heading 3</th>
            <td>Row 1 Cell 1</td>
            <td>Row 1 Cell 2</td>
            <td>Row 1 Cell 3</td>
            <td>Row 2 Cell 1</td>
            <td>Row 2 Cell 2</td>
            <td>Row 2 Cell 3</td> 


As we can see above this is a basic table using the HTML table tags along with thead and tbody.

Now, let’s take a look at the replacement:

First the markup:

<div class="table">
    <div class="thead">
        <div class="table-row">
            <div class="table-heading">
                <div class="table-cell">Heading 1</div>
                <div class="table-cell">Heading 2</div>
                <div class="table-cell">Heading 3</div>
    <div class="tbody">
        <div class="table-row">
            <div class="table-cell">Row 1 Cell 1</div>
            <div class="table-cell">Row 1 Cell 2</div>
            <div class="table-cell">Row 1 Cell 3</div>
        <div class="table-row">
            <div class="table-cell">Row 2 Cell 1</div>
            <div class="table-cell">Row 2 Cell 2</div>
            <div class="table-cell">Row 2 Cell 3</div>

Next, the style:

div.table {
    display: table;
div.table > div.thead {
    display: table-header-group;
div.table > div.tbody {
    display: table-row-group;
div.table > div.thead > div.table-row,
div.table > div.tbody > div.table-row {
    display: table-row;
div.table > div.thead > div.table-row > div.table-heading {
    display: table-cell;
    font-weight: bold;
div.table > div.tbody > div.table-row > div.table-cell {
    display: table-cell;

Now we have all the functionality of a table with none of the CSS styling issues and interacting with JavaScript is straight forward and simple.  The only real issue I see with this approach is the “div soup” that is seen in place of individual tags.  Additional styling attributes such as border, cell padding and cell spacing can be controlled using standard CSS properties such as border, padding, etc.

I’ve been implementing and using this approach for quite some time now with no issues and plenty of benefits.  Feel free to let me know your feelings about this approach.  Thanks.

8 thoughts on “Never Use HTML Tables, Ever!

  1. Charles

    I have always preached this but always run into resistance. I have found that styling tables is just bizarre and tedious as well as dealing with row and col span. My understanding is that tables also run specific code branches in some rendering engines just for table rendering which can trigger cross-browser differences/issues.

    My only concern is accessibility.

    1. godlikemouse Post author

      Hi Charles,

      I’ve run into the same thing, until it was applied and demonstrated. Once others saw what could be done (for example, having a table layout transform into a card layout when the browser was sized smaller) they changed their tune. Now with regards to column and row span, you are correct, there is no easy way around that with this approach. My own experience however, led me to believe that maybe row and column span approaches were incorrect as a whole. Keeping this line of though I instead changed how the data was presented by using tooltips or popovers along with ellipsed text. This approach may not work for everyone, but it has worked for us and very well. I can’t speak to the table rendering optimizations for specific browsers, I can say though I have seen no performance issues with this approach on Firefox, Chrome or IE.

  2. Mike Paul

    I don’t think it really counts as “not using tables” if you’re just telling the browser to render divs as if they were tables. It looks to me like you’re just reinventing the same table elements that HTML already provides.

    The documentation for the CSS class selector has the note:

    Because CSS gives considerable power to the “class” attribute, authors could conceivably design their own “document language” based on elements with almost no associated presentation (such as DIV and SPAN in HTML) and assigning style information through the “class” attribute. Authors should avoid this practice since the structural elements of a document language often have recognized and accepted meanings and author-defined classes may not.

    You’re doing exactly that.

    1. godlikemouse Post author

      Hi Mike,

      One of the main reasons for this approach is regarding JavaScript interaction and responsive or Zen CSS web design. An example you could try would be the following which might illustrate why this approach might be helpful.

      Try constructing a standard HTML table with multiple rows, then through JavaScript dynamically add and remove rows of data. Next, take that same table and make it change using responsive behavior from a table to something like a card view depending on browser width.

      Now try the exact same thing using the approach I described in this article. The main difference is that with the styled div approach, adding a removing rows is the same as it would be for any other element, this makes a big difference when using JavaScript frameworks such as jQuery and such. You no longer need to code a specific case when dealing with tables. With regard to styling the responsive divs into the card view, that’s also extremely simple and straight forward.

      If your current projects don’t require a responsive behavior, are not using a Zen approach or are not dynamically changing content on the front end, then by all means ignore this article. However if it does, then using any of the mentioned approaches listed in this article may assist in achieving those goals. As I stated in the article, I’ve been using this approach for quite some time with absolutely no drawbacks (other than the tables not using the actual table tag).

      In my experience there has never been an absolute hard rule as to what developers must always do (citing your CSS documentation blurb), there have almost always been reasons to bend or break the rules depending on the situation.

  3. SJones

    Thanks for the reply. While I’ve always agreed that using tables as layout was a non-semantic hack, I hadn’t understood the rush to throw out tables when used, semantically, for tables of data. Your answer, in short: Baggage and flexibility. Makes sense. Thanks for the clear markup example and explanation.

  4. SJones

    While this is certainly the modern, popular view of table markup, you really only gave two tangible reasons that “tables are evil”: Adding or removing rows via JavaScript. For this benefit, you incurred a 130% increase in markup. I’d argue that dynamically updating tabular data isn’t as common as displaying static data.

    Are there other advantages you didn’t mention that make the added markup worth it?

    1. godlikemouse Post author

      Hi SJones,
      There are a few, for instance when developing for responsive web, divs can offer an easy way to display the already structured content in a myriad of ways versus implementing overridden custom styles for formatting tables in a similar way. This is especially true when then intended outcome is something that may be completely different looking than a table or table like display.

      From a Zen approach, the divs offer a generally easy way to use CSS to change the entire layout when using multiple or swappable stylesheets.

      Mostly it makes things simpler from a dynamic JavaScript and CSS point of view.

      On the other side of coin, the added markup is really minimal and can be made even more minimal by using less obvious classes (which I used really just to illustrate what each class was doing). For example, classes could be “td, th, table, tr, thead, tbody” respectively.


Leave a Reply

Your email address will not be published. Required fields are marked *