Why is the Bootstrap grid layout preferable to an HTML table?

[Note: for those who may be confusing this question with "why not use tables for HTML layout", I am not asking that question. The question I'm asking is why is a grid layout fundamentally different from a table layout.]

I'm researching CSS libraries (in particular Bootstrap) for a project. I am a programmer rather than a web designer and I feel I could benefit from a library that encapsulates good design.

We all know that it's bad practice to use HTML tables to accomplish basic site layout because it mixes presentation with content. One of the benefits provided by CSS libraries like Bootstrap is that they offer the ability to create "grid" layouts without using tables. I'm having a little trouble, however, understanding how their grid layouts differ in any meaningful way from the equivalent table layout.

In other words, what is the fundamental difference between these two examples of HTML? Am I wrong in thinking that the grid layout is simply a table with another name?

<div class="row">
    <div class="span16"></div>
</div>

<div class="row">
    <div class="span4"></div>
    <div class="span4"></div>
    <div class="span4"></div>
    <div class="span4"></div>
</div>

and

<table>
  <tr>
    <td colspan=4></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
</table>

The difference is that the first example is semantically marked up, assuming the data being marked up is not actually tabular. <table> should only be used for tabular data, not for any data which happens to be displayed in a layout similar to a table.

It is correct though that using CSS packages like Bootstrap, which require you to assign classes to HTML elements which are not semantic but presentational, reduces the separation of content and presentation, making the difference somewhat moot. You should be assigning semantically meaningful classes to your elements and use lesscss mixins (or similar technology) to assign presentational behavior defined in the CSS framework to these classes, instead of assigning the presentational classes to the elements directly.

Say:

<div class="products">
    <div class="product"></div>
</div>

.products {
    .row;
}

.products > .product {
    .span16;
}

Note that I say should. In practice this is not necessarily always the more workable option, but it should be the theoretical goal.


I believe that CBroe comment is the best option, so I chose to clarify it.

Avoid div's. A div should be your last resort, not your first option. Instead, try to use Bootstrap classes on the actual elements. For instance:

<form class="container">
    <fieldset class="row">
        <label class="span4" for"search">Type your search</label>
        <input class="span6" type="text" id="search" />
    </fieldset>
</form>

It is a shame to use fieldset to contain a single field, but it is semantically best than using a div for the same thing. The HTML5 standard defines many new container elements, such as article, section, header, footer and many more. In some cases you will have to use div's, but if you minimize it's use then your code will be way more semantic.


The fundamental difference is that you can "reflow" the layout with Bootstrap for different display sizes simply using media queries without needing to change your markup. For example, I can decide that on desktops, I want your 4 divs to be on same row because user has high resolution wide display but on phones I want 2 dives on one row and next divs on next rows. So this way I can adapt my column count in each row using media queries. If you use hard coded HTML tables then it is very difficult to do this.

Having said that, I don't really like bootstrap implementation for the following reasons:

  1. It has breakpoints hard coded in pixels. This means, as phones and tables advance in display resolution, your website may start showing unexpected layouts on those devices. Pixel count is poor proxy for display size.
  2. It limits maximum used display area to 1170px which is again a bummer for users with nice wide displays they can actually use to see more content in your app.
  3. Bootstrap's layout is not source independent, i.e., you can't change column order that is set in HTML. This is however more of a pedantic point.
  4. The default layout is for very small resolution and higher resolution layouts trigger only when media queries fire, which IMO, is a poor choice considering phones will continue to have better resolution and sooner than later your website would have default layout set for outdated mobile devices.
  5. Bootstrap layouts are not truly "worry free" in the sense that you have to read their fine print to see all the bugs and browsers they didn't see worthy of supporting but which you may care about. If you are targeting users in South Korea or China, you would be in for surprise, for example.

So, not everything is gold in bootstrap and their approach is not necessarily always the best possible (as an aside, one other thing I despise in bootstrap is their obsession with so called "jumbotrones" - those real estate wasting inconvenient in-your-face headers - which I hope community doesn't start taking as "new standard"). Personally I use CSS table layout (display:table) these days which has similar benefits as bootstrap without hardcoding <table> in my markup. I can still use media queries to rearrange rows depending on portrait or landscape orientation, for example. However the most important benefit is that my layouts are truly pixel or even percentage independent. For example, in 3 column layout, I let content to decide how much space first and last columns should take. There is no pixel or even percentage width. The center column grabs up all the remaining space (which is good thing for my app, but it may not be for others). In addition, I use ems in media query break points which bootstrap surprisingly doesn't.