68

[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>
naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
Larry Lustig
  • 49,320
  • 14
  • 110
  • 160
  • 1
    possible duplicate of [Why not use tables for layout in HTML?](http://stackoverflow.com/questions/83073/why-not-use-tables-for-layout-in-html) – Quentin Jan 22 '13 at 14:45
  • 8
    @Quentin and close-voters: **This is not a dupe.** This question is not about why not to use tables, it asks about the difference between HTML tables and CSS tables as done by Bootstrap &co, which in practice comes down to very little difference in markup and functionality. – deceze Jan 22 '13 at 15:05
  • 13
    @Quentin: This is absolutely *not* a duplicate of that question (which I have read). I'm not asking why tables shouldn't be used. I'm asking whether and why grid layouts in Bootstrap and other libraries are fundamentally different from table layouts -- that is, why the "row" and "span" *classes* are better than row and cell *elements* and colspan attributes. – Larry Lustig Jan 22 '13 at 15:17
  • And to think, we were on the path to enlightenment.. remember http://www.csszengarden.com/ ? Except turns out css is more like assembly hell than python heaven – User Nov 05 '13 at 21:58
  • 3
    _“Why is the Bootstrap grid layout preferable to an HTML table?”_ – it __isn’t__, because that’s just terrible DIV soup. IMHO Bootstrap caters mainly to people who have no idea how to write semantic HTML in the first place. – CBroe Nov 13 '13 at 13:29

9 Answers9

33

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.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • 1
    I somewhat disagree. In the real world, absolute separation is not realistic. It's just a good guideline to separate style and content as best you can. You certainly don't need a preprocessor to achieve this. – Jezen Thomas Jan 22 '13 at 14:51
  • 4
    @Jezen I totally agree that in reality it's not a 100% attainable goal. That should not distract from the facts of what is good and what is bad, even if just in theory. At least *know* the evil you're choosing and why. :) – deceze Jan 22 '13 at 14:52
  • Why are the `row` and `span*` classes used in the grid layout less presentational than `` and `` elements in the table example? – Larry Lustig Jan 22 '13 at 15:22
  • 2
    @Larry They are not less presentational, they are *purely presentational* and *not semantical*. `` has a *semantic meaning*. Data marked up using a `
    ` can be parsed into other tabular formats, say (god forbid) an Excel sheet. `
    ` elements have no specific meaning though. `
    ` doesn't mean anything more than `
    `. Separation of meaning and presentation.
    – deceze Jan 22 '13 at 15:31
  • 1
    Hmmm. I think I disagree. You *could* define an abstract concept of a `row` such that it implied nothing about the physical presentation of the object. But that is clearly *not* what this kind of grid layout does. The tutorials I've read on the grid layout always start by showing a concrete picture of what the grid looks like as a contract, more or less, of how your grid-marked-up content will appear. It's not like `flargleborg` but more like `flargleborg-red`. Am I wrong? – Larry Lustig Jan 22 '13 at 15:35
  • @Larry This appears to go back to the "why should I not use HTML tables" question. If you understand *that* argument, the answer should be quite apparent. You use CSS grids to layout non-tabular data in a way that resembles a table and may even be achievable with a table; but you don't use `` elements because your data is not tabular. If your data *is* tabular, use a `
    `.
    – deceze Jan 22 '13 at 15:51
20

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.

Community
  • 1
  • 1
Metalcoder
  • 2,094
  • 3
  • 24
  • 30
  • 6
    This answer is the first time this pattern ever made sense to me. When people just replace every html element with div then do all layout in css and JavaScript it seemed like a giant waste of the entire HTML spec. But to use these patterns to enhance existing html and reduce the amount of extra tags does make perfect sense. – Matthew Whited Aug 22 '14 at 09:42
  • Is it right to have `.container` on a `
    ` tag? I thought `.container` is the outermost containing element (mostly `
    `) and you can only apply `.form-horizontal` if you want a horizontal form, else don't attach any classes to the form (BS3 does already slightly control it). then have `.row` -> `.col-XX-yy` -> `.form-group` -> `.label-control` for `
    – Roland Mar 20 '18 at 10:17
12

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.

Shital Shah
  • 63,284
  • 17
  • 238
  • 185
  • 2
    The "reflow" point is good and not mentioned in any other answers. The coined term for the reflow concept is "responsive". – Niko Bellic Dec 20 '17 at 01:16
4

I use the Bootstrap grid for page layout, tables for tabular data.

I think of the grid in Bootstrap, not as a grid in the developer sense, like a gridview control, but more in the design page-layout sense - as a grid to contain the page contents. And even though the Bootstrap grid could be also used to create a conventional grid containing tabular data, as deceze pointed out, this kind of grid is better suited for HTML tables - which are still acceptable to use in this scenario.

DShultz
  • 4,381
  • 3
  • 30
  • 46
3

if you just use tables i think you will miss out on alot of flexibility in re-sizing your document for mobile/tablets without having to make a separate page for each device. once your table structure is defined all you can really do is zoom in and out.

3

While there's not necessarily much semantic difference between the two sets of markup (since the classes used by Bootstrap's grid system are indeed purely presentational), one very important distinction is that the grid system is much more flexible.

It would be very difficult, for example, to make your table-based layout respond to different screen sizes. There's no way to tell the browser to display one td element below another td in the same row. Whereas with the div example, that's easy to do, and the same markup can be presented in different ways even when the classes are "presentational" in the sense that they define the relative proportions and positioning of the elements on the page.

Louis Simoneau
  • 1,781
  • 14
  • 18
1

If I may, I'd like to summarize what I gathered from the other comments and the link explosion I experienced from this page:

The problem with using tables isn't the grid layout, it is the attempt to express it with HTML instead of CSS.

Bootstrap allows grid layouts through (mostly) pure CSS, which is why it is OK. The 'mostly' part comes because your HTML will still be contaminated by your layout data, but more subtly:

<nav class="span4"> ... </nav>
<article class="span8"> ... </article>

This is surely significantly more semantic and maintainable than the old tabular designs, but the 'span4' and 'span8' are still display-data embedded into our HTML. However, since design can never be truly be decoupled from our data (e.g., nested divs), this is a reasonable price to pay.

That being said, even this coupling can be broken, if you use some more modern CSS features provided by a pre-processed language such as LESS. The same example:

<nav id="secondary-nav"> ... </nav>
<article id="main-content"> ... </article>

Coupled with the following LESS:

#secondary-nav{
    .span4;
    // More styling (padding, etc) if needed
}
#main-content{
    .span8;
}

This creates fully decoupled HTML and Stylesheet, which is ideal, because the HTML is cleaner and more readable, and redesigns can be made with less HTML modification. However this only works if you use LESS or some other CSS pre-processor, because CSS currently does not support mixins (AFAIK).

We already use LESS in my workplace, so I know I'll be pushing towards using this type of solution. I'm a very strong believer in semantic HTML and data-design decoupling. :)

Gilthans
  • 1,656
  • 1
  • 18
  • 23
0

Basically DIVs are DIVs & Table elements are simply table elements. The problem with tables is often just keeping track of all of the columns & the rows because it is ultimately a strict data construct. DIVs are far more flexible & forgiving.

For example, if you wanted to to take the four DIVs with the class that equals "span4" and just change them to a 2 column width, all you would need to do is adjust a wee bit of CSS for the outer class "row" and maybe the class "span4". In fact when doing DIVs like this I would avoid calling individual DIVs "span4" or some other number.

My approach would be to create a parent wrapper DIV that is called "rowspan" and the inner DIVs would have some generic ID like maybe "cell".

<div class="rowspan">
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
</div>

Each "cell" class could have a width of 100 pixels for example, and then the parent "rowspan" could be 400 pixels. That would equate to 4 columns in a row. Want to make it 2 columns? No problem! Just change "rowspan" to be 200 pixels wide. At this point it is all in CSS so it's easy to do without rejiggering page structure in the DOM.

But with tables? Not easy. You would have to basically re-render the table with </tr><tr> tags to create new rows.

Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
  • Again, I'm having trouble understanding how your example differs in theory from a `` element containing four ``s. You even use the class name "cell". It seems to me that you've encoded the presentation (four cells in a row) into the HTML. – Larry Lustig Jan 22 '13 at 15:29
  • `` is a DOM level element. CSS resides outside of the DOM. By using `
    ` elements with a decent CSS taxonomy you gain more flexibility & don’t have to resort to changing the DOM by adding `` elements. Meaning you can create—for example—a PHP script that can simply spit out `
    ` elements with specific CSS classes instead of having to do the crazy calculations one would have to do to create `` elements.
    – Giacomo1968 Jan 22 '13 at 15:31
  • Or another way to understand it, remove any CSS logic & classes and a `` is simply a `` row and will never—and can never—be anything else. But a `
    ` is more flexible & can allow layouts that are visually the same as a `
    ` but with many more options without having to tear apart & rework the DOM structure of a `
    `.
    – Giacomo1968 Jan 22 '13 at 15:38
  • If you look at the grid layout I quoted (which I copied from a tutorial extolling the virtues of Bootstrap), it appears to me that when using the 960 grid, all the calculations for the layout are required to be done by the designer and hard-coded into the HTML. The entire purpose of the grid it so guarantee that you'll have cell X in "this" location and cell Y in "that" location and that you will not have the flexibility to make two substantially different presentations by changing the CSS. – Larry Lustig Jan 22 '13 at 15:39
  • 1
    I understand your argument that `
    ` offers more flexibility to change the presentation using CSS, and why that's valuable. My question was never about the benefits of separating presentation from meaning. However, the grid layout systems seem to take back that flexibility by hardcoding row and column structures into the HTML and my question is -- am I wrong that that's what the grid layouts are doing?
    – Larry Lustig Jan 22 '13 at 15:41
  • I have no idea what you mean by "However, the grid layout systems seem to take back that flexibility by hardcoding row and column structures into the HTML and my question is -- am I wrong that that's what the grid layouts are doing?" What grid layout systems? Technically speaking one need not use specific class names or even use any class name. – Giacomo1968 Jan 22 '13 at 15:50
  • My question references the Bootstrap grid layout system, so you can use that one as my prime example, but there are quite a few competing grid CSS libraries around. They all encode rows with a set number of columns, and cells that span a set number of columns, in the HTML via class names. – Larry Lustig Jan 22 '13 at 15:52
  • Okay, well if that is the case then perhaps they are not approaching the way CSS works for a `
    ` in this case as efficiently as one should. But in general, I don’t use tools like that & do pure CSS by hand in many cases. And I can assure you there are more headaches down the line when using `` tags versus `
    ` & CSS. It’s far more proactive in the long term life of the coding.
    – Giacomo1968 Jan 22 '13 at 16:00
  • 0

    Version with table, tr, td depends on browser algorithms - wrapping, dynamic width, margins, centering etc. Version with div can be more easily tuned by css and scripts.

    Andrei
    • 882
    • 8
    • 13