Update: It’s now been 9 years since I asked this question and the world has changed. We now have flexbox and css grid as widely supported options, so using tables
for layout (either actual or via display: table) isn’t needed anymore. This question is left here for historical purposes.


In modern web development I’m coming across this pattern ever more often. It looks like this:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><div class="table">
<div class="row">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
</div>
</div>
</code>
<code><div class="table"> <div class="row"> <div class="cell"></div> <div class="cell"></div> <div class="cell"></div> </div> </div> </code>
<div class="table">
    <div class="row">
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
    </div>
</div>

And in CSS there is something like:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>.table { display: table; }
.row { display: table-row; }
.cell { display: table-cell; }
</code>
<code>.table { display: table; } .row { display: table-row; } .cell { display: table-cell; } </code>
.table { display: table; }
.row { display: table-row; }
.cell { display: table-cell; }

* (Class name are illustrative only; in real life those are normal class names reflecting what the element is about)

I even recently tried doing this myself because… you know, everyone’s doing it.

But I still don’t get it. Why are we doing this? If you need a table, then just make a blasted <table> and be done with it. Yes, even if it’s for layout. That’s what tables are for – laying out stuff in tabular fashion.

The best explanation that I have is that by now everyone has heard the mantra of “don’t use tables for layout”, so they follow it blindly. But they still need a table for layout (because nothing else has the expanding capabilities of a table), so they make a <div> (because it’s not a table!) and then add CSS that makes it a table anyway.

For all the world this looks to me like putting arbitrary unnecessary obstacles in your way and then doing extra work to circumvent them.

The original argument for moving away from tables for layout was that it’s hard to modify a tabular layout afterwards. But modifying a “faux-table” layout is just as hard, and for the same reasons. In fact, in practice modifying a layout is always hard, and it’s almost never enough to just change the CSS, if you want to do something more serious than minor tweaks. You will need to understand and change HTML structure for serious design changes. And tables don’t make the job any harder or easier than divs.

In fact, the only way I see that tables could make a layout difficult to modify, is if you abused them and created an ungodly mess. You can do that with divs too.

So… in an attempt to change this from a rant into a coherent question: what am I missing? What are the actual benefits of using a “faux-table” over a real one?

About the duplicate link: This isn’t a suggestion to use another tag or something. This is a question about using a <table> vs display:table.

21

This is a common pattern for making responsive tables. Tabular data is tricky to display on mobiles since the page will either be zoomed in to read text, meaning tables go off the side of the page and the user has to scroll backwards and forwards to read the table, or the page will be zoomed out, usually meaning that the table is too small to be able to read.

Responsive tables change layout on smaller screens – sometimes some columns are hidden or columns are amalgamated, e.g. name and email address might be separate on large screens, but collapse down into one cell on small screens so the information is readable without having to scroll.

<div>s are used to create the tables instead of <table> tags for a couple of reasons. If <table> tags are used then you need to override the browser default styles and layout before adding your own code, so in this case <div> tags save on a lot of boilerplate CSS. Additionally, older versions of IE don’t allow you to override default table styles, so using <div>s also smooths cross-browser development.

There’s a pretty good overview of responsive tables on CSS-Tricks.

Edit: I should point out that I’m not advocating this pattern – it falls into the divitis trap and isn’t semantic – but this is why you’ll find tables made from divs.

6

The question is if the data is semantically a table (i.e. a set of data or units of information logically organized in two dimensions) or you just use the grid for visual layout, e.g. because you want a sidebar to expand or something like that.

If your information is semantically a table, you use a <table>-tag. If you just want a grid for layout purposes, you use some other appropriate html elements and use display:table in the style sheet.

When is data semantically a table? When the data is logically organized along two axes. If it makes sense with headers for the rows or columns, then you might have a semantic table. An example of something which is not semantically a table is presenting a text in columns like in a newspaper. This is not semantically a table, since you would still read it linearly, and no meaning would be lost if the presentation was removed.


OK, why not use <table> for everything rather than only for something that is semantically a table? Visually it is obviously the same (since the table element just have display:element in the default style sheet).

The difference is that the semantic information can help alternative user agents. For example a screen reader might allow you to navigate in two dimensions in the table, and read the headers for a cell for both axes if you forget where you are. This would just be confusing if the table was not semantically a table but just used for visual layout.

The <table> versus display:table discussion is just a case of the more general principle of using semantic markup.
See for example: Why would one bother marking up properly and semantically? or Why is semantic markup given more weight for search engines?

In some places you might actually be legally required to use semantic markup for accessibility reasons, and in any case there is no reason to purposefully make your page less accessible.

Even if you don’t care for disabled users, having presentation separate from content gives you benefits. E.g. your three column layout could be presented in a single columns on a mobile using an alternative stylesheet.

19

Actually, I would say that the use of class names like “table” in your example demonstrates how people don’t actually understand what they’re doing when trying for semantic markup. They get marks for trying to show that the content is not tabular data, but they lose marks for bad class names.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><div class="table">
<div class="row">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
</div>
</div>
</code>
<code><div class="table"> <div class="row"> <div class="cell"></div> <div class="cell"></div> <div class="cell"></div> </div> </div> </code>
<div class="table">
  <div class="row">
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
  </div>
</div>

All that this developer has done is replicate the original <table> markup with CSS class names. This means as soon as this layout is not a table, the class names are at odds.

What this developer should have done is consider what information is in the table – is it a thumbnail gallery? Well, then:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><div class="thumbnail-gallery">
<div>
<div class="thumbnail">
<img src="" />
<p>Some text</p>
</div>
<div class="thumbnail">
<img src="" />
<p>Some text</p>
</div>
<div class="thumbnail">
<img src="" />
<p>Some text</p>
</div>
</div>
</div>
</code>
<code><div class="thumbnail-gallery"> <div> <div class="thumbnail"> <img src="" /> <p>Some text</p> </div> <div class="thumbnail"> <img src="" /> <p>Some text</p> </div> <div class="thumbnail"> <img src="" /> <p>Some text</p> </div> </div> </div> </code>
<div class="thumbnail-gallery">
  <div>
    <div class="thumbnail">
      <img src="" />
      <p>Some text</p>
    </div>
    <div class="thumbnail">
      <img src="" />
      <p>Some text</p>
    </div>
    <div class="thumbnail">
      <img src="" />
      <p>Some text</p>
    </div>
  </div>
</div>

Now I can create some adaptive CSS:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>@media screen {
.thumbnail-gallery {
display: table;
border-collapse: collapse;
width: 100%;
}
.thumbnail-gallery > div {
display: table-row;
}
.thumbnail-gallery .thumbnail {
display: table-cell;
border: 1px solid #333333;
}
}
@media screen and (max-width: 640px) {
/** reset all thumbnail gallery elements to display as block and fill screen **/
.thumbnail-gallery,
.thumbnail-gallery > div,
.thumbnail-gallery .thumbnail {
display: block;
width: 100%;
}
}
</code>
<code>@media screen { .thumbnail-gallery { display: table; border-collapse: collapse; width: 100%; } .thumbnail-gallery > div { display: table-row; } .thumbnail-gallery .thumbnail { display: table-cell; border: 1px solid #333333; } } @media screen and (max-width: 640px) { /** reset all thumbnail gallery elements to display as block and fill screen **/ .thumbnail-gallery, .thumbnail-gallery > div, .thumbnail-gallery .thumbnail { display: block; width: 100%; } } </code>
@media screen {
  .thumbnail-gallery {
    display: table;
    border-collapse: collapse;
    width: 100%;
  }

  .thumbnail-gallery > div {
    display: table-row;
  }

  .thumbnail-gallery .thumbnail {
    display: table-cell;
    border: 1px solid #333333;
  }
}

@media screen and (max-width: 640px) {
  /** reset all thumbnail gallery elements to display as block and fill screen **/
  .thumbnail-gallery,
  .thumbnail-gallery > div,
  .thumbnail-gallery .thumbnail {
    display: block;
    width: 100%;
  }
}

Why divs and not tables

A table contains tabular data – presentation of a table is inextricably linked to the structure of a table. Tabular data will always need to be in tabular form no matter where you put that content or on what screen/device you want it to display.

A thumbnail gallery (or many other things, like a registration form, a menu, and more) is not tabular data. It may be presented like a table in some design layouts, but in other cases, like narrow phone screens, you want it using more traditional block layouts. Or perhaps you want to display thumbnails in a sidebar instead of in the main content area.

Your choice is now to output different markup for the wide screen content (tables) and sidebar or narrow screen content (divs) – which means your server side scripts will have to be aware of where the content is going if you’re building this programmatically – or you have your server side script output the same markup (because it shouldn’t care where you’re putting this) and use different CSS rules for the different situations.

So, then you have a choice of always outputting tables, and then overriding the natural table display rules with block (which really should grind some gears in any developers head), or going with well labelled divs which allow more flexible approaches to styling.

And best practices for several years now has been to avoid tables when not needing to present tabular data.

7

In the olden days, the table rendering engine “appeared” slower when you used percentages for column widths. The engine essentially had to download the entire data set before it would then begin figuring out how big everything was to draw it on the screen.

The DIV engine was different. As the browser encountered a DIV it would go ahead and place it and start filling the content inline. Of course, div’s might jump around as the data finished loading. Hence why I have appeared in quotes above. The time frame for completion of both was the same, however tables weren’t drawn until the end which meant the user wasn’t sure if it was loading or not for a second or two.

This became worse as tables were nested.

There were then (and still exist) ways to make table rendering FAR FAR faster. Basically by giving it a hint that column sizes aren’t changing, then the browser starts rendering tabular data immediately. Ultimately this means that tables can actually display in the correct position faster than divs giving them the appearance of being better.

But that’s not the whole story. The rest of it is that most devs simply don’t bother to learn their craft well enough to know this. Instead they jump on various bandwagons and go with whatever code they can copy/paste from. Even today I find that very very few web developers know the difference from one doctype to the next – and that is the number one reason why various sites have all sorts of workarounds to cover various browsers.

So, +1 to you for asking the question.

8

If I can get a little “meta” here, this brings two problems to my mind:

One: Someone proposes a rule for some good reason, and people completely miss the point by following the technical letter of the rule while ignoring the spirit. They find some way to accomplish all the bad things that the rule was trying to prevent, while still technically following the rule as worded.

Two: Someone sees a problem and proposes a rule to prevent it. Others see the value of this rule. Then they insist on blind devotion to this rule without regard to the original problem it was supposed to solve and/or regardless of what other problems it creates. I’ve had many conversations where someone says, “You must do X because that’s the rule”, and then I ask, “But why should we do X?”, and they look at me with bafflement and exasperation and say, “But I just told you! Because it’s the rule!” I reply, “But it seems to cause more problems than it solves. I think we’d be better off to do Y.” And then the person says, “No, look, I’ll show you. See, it’s right here in this book. X is the rule.”

In this case, we have a problem: The table tag does two things: One, it controls the layout of a document. Two, it conveys the idea that the enclosed data is made up of rows and columns of numbers or other data.

So many people proposed the solution: Don’t use table tags to control layout of things that aren’t logically “tables”. Use CSS.

But there’s a problem with this solution. The table tag and its subtags do many very useful layout functions that are not easy to achieve using CSS, and when they can be achieved, the code necessary to do it is often cumbersome — difficult to read and difficult to maintain. Why should we do things in a clumsy, difficult way when there is a clean, easy way?

Personally, I think we would have been better off to just declare, “The fact that something is inside a table tag does not necessarily mean that it represents rows and columns of numbers.” This would not have been an outrageous pronouncement. I have never heard someone say that the “p” tag can only be used for things that are really paragraphs of grammatically-correct, logically-constructed English sentences. I’ve never heard someone say that it is wrong to use a “ul” tag for a list that does, in fact, come in a logical order, just because you wanted bullets and not sequence numbers. Etc.

8

There are already tons of great answers here. But I wanted to add that table elements have rendering limitations that don’t exist for div elements. Try and make a table that does virtual scrolling (like: SlickGrid, DataTables, and others) and you’ll be sorely disappointed. It just doesn’t work. Most (All?) modern Javascript grids use divs because the css allows for much more flexible rendering.

There are other limitations as well. My general rule is that if I’m going to see the whole table on a single screen, and I don’t want any/much custom rendering for it I use a table element, otherwise I go with divs because I can control the results much, much more easily.

HTML and CSS have evolved a degree of flexibility that means that even conceptually “block” elements like <div> (HTML’s oldest and most general form of block content) don’t need to be displayed as blocks:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>div { display: inline; }
</code>
<code>div { display: inline; } </code>
div { display: inline; }

As you note, <div> can be repurposed to emulate <table> and its fellow travelers. Actually, most tags can. Given their special roles, I doubt you could usefully remap macro tags like <html>, <head>, <body>, and <script>, but “common” tags like <div>, <p>, <b>, <em>, <span>, and <pre>? Up for grabs. Make the inline tags blocks, the blocks inline, the pre-formatted tags flow, the stationary ones float. Go crazy, if you like!

It’s possible. You may want to spin a yarn about how we should all use “semantic markup” blah blah blah, or believe with the Pythonistas that “There should be one–and preferably only one–obvious way to do it.” Yet Tim Toady is a clever and curious guy. Given a free hand, he’ll explore them all. That includes using the available flexibility to make substitutions. Some are wise, some will be proven otherwise. But trial, error, and experience is the only way to find that out. So the sufficient conditions for substitution are present.

I don’t think it’s overstepping to say that substitution is also necessary. At minimum, it’s extremely convenient. For a long time, HTML didn’t have <menu>, <section>, or <aside> elements. Yet web pages and apps everywhere have menus, sections, and sidebars. How? Because HTML list elements (<ul>, <ol>, and <li>) were easily repurposed and some usages re-classified as menu containers and parts. <div> could stand in for <article>, <section>, <aside>, <figure>, and <summary>. HTML5 has caught up with, and added bespoke elements for, some previously-unaddressed use cases. It’s a great update and correction to accommodate common, real-world use.

Even so, there remain a lot of common idioms that don’t have bespoke tags or semantic models. Things like pages, footnotes, pull-quotes, comment streams, associated avatars, “likes,” subheads, and subtitles that I and many others use every day. What are we to do? What we can. Repurpose “close but inexact” elements with classes and ids to stand in and support our work for the next five or ten or however many years until HTML6 or HTML7 catches up. HTML/CSS’s “yes, it’s an X, in theory, but we’re going to tag it and work with it as a Y” ability is incredibly convenient. Indispensable, really. It makes Web content flex, and not be brittle.

Going even further, “semantic markup” has irreducible limitations. That’s true of any kind of rigorous structure you can imagine for content.

Standard formats cannot encompass the entire wealth of human need, desire, and variety. They will always will be “behind the curve” of what people are doing now. How they are innovating. Heck, HTML5 is still behind the curve on footnotes, subheads, and other printing innovations of the 17th century. It lacks features essential to many information workers and content creators. So we improvise.

Even more unchanging is that information doesn’t abide by one set of rules. Sure, it starts as a table. But maybe you just want the summary–say the title for each row, as a list. Maybe it takes up too much space, and you’d like it as a space-saving inline list. Maybe you have records you just want the title of, then if you click, you see the underlying details. Or you want items in a complex list or table to be grouped and categorized. Oh, now you want it transposed and categorized a different way. Or the values plotted as a bar chart. These are things done every day in apps, spreadsheets, and data visualization. They are part and parcel of our information landscape, and what we want and need to do on the web. Humans constantly reorganize the form and presentation of our data. It isn’t just one thing, or one format/layout, or one concept. It’s fungible, with semantics depending on the circumstance and on choices users make interactively. Yes, mark text as “emphasized” (<em>), but that’s just a convention. I’ve worked on documents with at least a half-dozen different kinds of “emphasis.” We need to be able to customize and remap that for different uses, different interpretations. One kind of HTML emphasis? Excruciatingly reductionistic. Limiting. Brittle. The same is true for <table>, <p>, etc.

It’s great to have tags/elements that help organize the entire community’s thinking about “what goes where.” That helps establish conventions and idioms, and makes us collectively more efficient. But the ability to remap things, to redesignate and repurpose those structures? That’s part and parcel of the Web’s inclusiveness and its success.

5

Use cases matter. There is a big difference between layout/presentation in a content page and in an application. In content, semantics matter a great deal for SEO-awareness and usability. In these cases, using tables to present tabular data is in general the right thing to do. As others have noted, search engines will penalize you and you may even run afoul of usability laws if you are required by statute to conform to govt usability guidelines.

In a web application, developers may opt to create entirely separate views for SEO and usability purposes. Responsive design has led people to build views that can handle desktop and mobile layouts, and divs are better than tables in those use cases.

Take ecommerce sites, for example. Viewing a list of products in a browse or search result shows, in general, a list of products in tabular format, but those views may well be generated using divs (which provide more generic and flexible layout and styling options) rather than tables. Amazon and eBay are good examples of this approach. Inspect a search result on either site and you will see a deeply nested set of divs.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật