3

A classical piece of web development mantra is: "Only use tables for tabular data". This has its roots in the elder days, when tables were abused for every possible layout task imaginable.

While I too hold to this rule whenever possible, there are now and then layout tasks which I just cannot solve without a table - or tasks that straddle on the boundary between "tabular data" and "non-tabular data". This is one of them.

The situation is a totally classical one:

   Name: […]
Surname: […]
    Age: […]
    Job: […]

The […] are meant to be textboxes. Is this tabular data? Should I use a table for arranging these labels and textboxes or some unholy mashup of <div>s and <span>s? The table would make it easier to provide the proper vertical alignments and help lining up labels of unknown widths. But would it be "proper", or just another "hack that floats my boat"?

And what if we look at it like this?

 Field | Value
 ---------------
   Name: […]
Surname: […]
    Age: […]
    Job: […]
Vilx-
  • 104,512
  • 87
  • 279
  • 422
  • 4
    If it feels right it is right. Use a table. – jackJoe Oct 24 '13 at 14:57
  • While I'm totally for using tables when in doubt, there are cleaner approaches that don't need them and do *not* lead to disgusting tag soup. Let me look up an example – Pekka Oct 24 '13 at 14:57
  • 6
    No, forms are not tabular data. Generally. What you have in the 2nd code block could be presented in a `` though. (E.g. a data table with records that have edit functionality.)
    – Šime Vidas Oct 24 '13 at 14:57
  • 1
    See e.g. http://alistapart.com/article/prettyaccessibleforms – Pekka Oct 24 '13 at 14:59
  • 2
    Twitter Bootstrap, aware of html standards, does not use tables for their [horizontal forms](http://getbootstrap.com/2.3.2/base-css.html#forms) – Laurent W. Oct 24 '13 at 15:00
  • Whats the matter with using a main container and then just labels/inputs? I would say that a div or block element would be better just because it would be less html to write. – Josh Powell Oct 24 '13 at 15:04
  • If you can classify the information you're wanting to display by beginning with "this is a table of...", *without* using words like "form" or "list" then a table should be perfectly acceptable. – James Donnelly Oct 24 '13 at 15:06
  • The problem with fixed-width labels is vertical alignment when either the label or the input field exceeds a single line height. In this case the elements are aligned by their bottoms, while a visually pleasing layout would need them to align by tops. A layout where the label is above the input field would solve this, but waste more screen real estate. – Vilx- Oct 24 '13 at 15:11
  • @Pekka웃 - that too uses fixed-width labels. See my previous comment. – Vilx- Oct 24 '13 at 15:32

5 Answers5

4

First of all, thanks for a good question!

This is obviously a form, not a table. The layout of it doesn't really matter, the point of a table is to designate that you are displaying data that lends itself to tabulate (think of it as a composite of simple lists.) Your use case here is to gather input, it doesn't matter whether its layout kind'a sort'a looks like a form.

Of course, none of this matters if you don't really care about semantics; in which case I say use whatever you want. In any event there are plenty of examples and frameworks out there that'll do what you want, but it's not particularly difficult to do by yourself either. And in fact, it can be very much like laying out a table, if you so wish. I'll walk you through it.

(tl;dr)

First, some markup:

<form>
  <label><span>Name:</span><input name="name" type="text"></label>
  <label><span>Surname:</span><input name="surname" type="text"></label>
  <label><span>Age:</span><input name="age" type="text"></label>
  <label><span>Job:</span><input name="job" type="text"></label>
</form>

This is not particularly tricky markup. I've not added any classes as you can see, and I'll get to that in a second. But first, I wanted to show you, without any extra markup, how to turn this into a layout like that you requested:

form {
  display: table;
}

label {
  display: table-row;
}

label > * {
  display: table-cell;
}

label > :first-child {
  text-align: right;
  padding-right: 10px;
}

That's it really. By using css and the table, table-row and table-cell headers for the display values, it's dead simple to create a table like layout without having to sacrifice semantic markup. This css doesn't change the semantics or accessibility of your form, it just provides clues to the browser how it should lay things out. Now, you also asked about adding a header to this. Changing the markup to the following, will unfortunately not really work:

<form>
  <div>
    <span>Field</span><span>Value</span>
  </div>
  <label><span>Name:</span><input name="name" type="text"></label>
  <label><span>Surname:</span><input name="surname" type="text"></label>
  <label><span>Age:</span><input name="age" type="text"></label>
  <label><span>Job:</span><input name="job" type="text"></label>
</form>

This is because our styling rules doesn't include any selectors for the div. Now, there are a number of ways this could be fixed, with various different pros and cons. You'll probably run into people that have one thing or another to say about best practices in this area, but honestly it mostly comes down to what works for you. I'd say so long as you keep the markup accessible for humans and robots alike – this does mean trying to stay semantic and make use of microformats, amongst other things – then adding whatever extra cherries on top to get the job done is A-OK!

Anyway, here's one way of doing it, to get your creative juices flowing. First, the markup:

<form>
    <div class="form-row">
      <span>Field</span><span>Value</span>
    </div>
  
    <label class="form-row"><span>Name:</span><input name="name" type="text"></label>
    <label class="form-row"><span>Surname:</span><input name="surname" type="text"></label>
    <label class="form-row"><span>Age:</span><input name="age" type="text"></label>
    <label class="form-row"><span>Job:</span><input name="job" type="text"></label>
</form>

And then the css:

form {
  display: table;
}

.form-row {
  display: table-row;
}

.form-row > * {
  display: table-cell;
}

.form-row > :first-child {
  text-align: right;
  padding-right: 1em;
}

As you can see all that had to change was that we introduced the class form-row to classify our content such, and replaced the label selectors in the css with .form-row. Now there are plenty of ways to go with this and I hope you take some time to play around with it, because there's plenty to learn (semantics, microformats, css practices etc.)

Hope this helps!

Community
  • 1
  • 1
Marcus Stade
  • 4,724
  • 3
  • 33
  • 54
2

Tabular-data describes a collective form of definite information. A form is not "tabular-data", it is interactive and not even really information for the visitor of the website, rather, it is information that (usually) gets sent, therefore it's fair to consider it incorrect to view changeable forms as "tabular-data." (Then again, it really depends on the usage, but I'm assuming you mean forms as in the practical and semantic purpose).

As far as a practice for styling forms, I usually tend to use divs and ul li combinations, as a form element is in fact a list of information. It even comes with (very limited, but still) some formatting options such as fieldset, legend, etc. I would consider looking into those as well.

Then there's the other side of the force (not necessarily the dark side, just, the alternative side) where semantics, while they matter, shouldn't be turned into a religious discipline. If tables work for forms, then so be it. You cannot apply a single set of semantic rules to every single situation. I've found myself saying this a lot, lately, but I'll say it again, every situation is different.

Jace Cotton
  • 2,004
  • 1
  • 21
  • 38
1

Well, using table or not depends, but if you are going to design a form, using table element is not the only thing which can design it perfectly, if you want, simply use an ul element with label and see how flawlessly you design the same thing without table or div

Demo

ul {
    margin: 50px;
}

ul li {
    margin-bottom: 10px;
    font-family: Arial;
}

ul li label {
    display: inline-block;
    width: 100px;
}

Infact you can use float on the li by assigning a fixed width to your ul element, this will result in a two column form, increase the width and make it three, so you don't need table here.

Mr. Alien
  • 153,751
  • 34
  • 298
  • 278
  • The problem with fixed-width labels is vertical alignment when either the label or the input field exceeds a single line height. In this case the elements are aligned by their bottoms, while a visually pleasing layout would need them to align by tops. A layout where the label is above the input field would solve this, but waste more screen real estate. – Vilx- Oct 24 '13 at 15:24
1

The example you provided does not require a table... And not does resort into an "unholy mashup" of divs.

<div>
    <label for="x"></label>
    <div class="value">
        <input id="x" type="text">
    </div>
</div>
<!-- rinse, repeat -->

CSS:

label {
   min-width: 8em; /* or whatever makes sense */
   display: inline-block;
   text-align: right;
}

.value {
   display: inline-block;
}
adamb
  • 4,815
  • 1
  • 25
  • 40
  • The problem with fixed-width labels is vertical alignment when either the label or the input field exceeds a single line height. In this case the elements are aligned by their bottoms, while a visually pleasing layout would need them to align by tops. A layout where the label is above the input field would solve this, but waste more screen real estate. – Vilx- Oct 24 '13 at 15:23
  • From a design standpoint, placing your labels on top allows for the lightest cognitive load: http://ux.stackexchange.com/a/8874 Vertical screen real-estate is much more plentiful then horizontal on the web - Users anticipate vertical scrolling. – adamb Oct 24 '13 at 15:34
  • Hey, do you have anything that would support the "users anticipate vertical scrolling" statement? It's really offtopic, but I've had one debate about this at work already, and it would be really nice if I had something to back my views up with. :) – Vilx- Oct 24 '13 at 15:42
  • Here's a bit from [Jakob Nielsen (2005)](http://www.nngroup.com/articles/scrolling-and-scrollbars/) on scrolling & scrollbars: **"On the Web, users expect vertical scrolling. As with all standard design elements, it's better to meet user expectations than to deviate."** I like to think this _more_ true today due to mobile browsing. – adamb Oct 24 '13 at 15:56
1

While I too hold to this rule whenever possible, there are now and then layout tasks which I just cannot solve without a table

Table elements have some pretty cool layout properties, and yes, there are times that those properties are needed. In these cases, CSS has the ability to set elements to display like various table elements, while keeping your code semantically correct as you would not actually using tables elements.

This includes properties such as display: table; display: table-cell;, display: table-row;

In terms of your example.. Tabular data is used to display information to a user.. placing inputs or textareas inside of a table would not be semantically correct. However, if you were to have that same format, with pre-existing data just being displayed, I would say that a table would be acceptable.

That format layout can be made with css fairly easily, using anything from floats, display: inline-block; or the table display properties mentioned above.

Blake Mann
  • 5,440
  • 23
  • 37
  • When using a `
    ` with `display: table-cell` I feel like I'm lying even to myself. If it needs to be a table cell then, well, one should use a table cell. Not some tag with a secret identity that might throw a future maintenance developer off for hours trying to figure out why a simple `
    ` is doing something it shouldn't.
    – Vilx- Oct 24 '13 at 15:26
  • 2
    You are looking at this the wrong way. By that logic, you should never use the `display` property at all.. even for 'inline' or 'none'. The purpose of the property is to make an element behave in a way other than it normally would, and there is nothing wrong with doing so. Semantics in code are important for HTML, and even if something looks tabular it does not mean that it is, and shouldn't exist in a table. Changing the way that an element appears does not affect it's semantic meaning, and anyone who was to disable their CSS would see the elements displayed in "semantically proper" fashion. – Blake Mann Oct 24 '13 at 15:36
  • @BlakeMann But you have to be careful not to use HTML for something CSS is better fit to do, and not use CSS for something HTML is better fit to do. Imho using CSS `table-...` value is the equivalent of using `b, i, u, s` HTML elements. – Jace Cotton Oct 24 '13 at 15:47
  • Using `b, i, u, s` tags is "wrong" because they serve the sole purpose of altering appearance... A job for CSS. Using CSS `table-...` is also intended for the sole purpose of altering the appearance of elements while retaining their semantic meaning in HTML, which is why I don't think they are equivalent. There are certain layout tasks which cannot be accomplished without `display: table-cell;` (or atleast not without great effort), such as a 3 column layout with 1 fixed width and 2 fluid width columns, but yet that should not ever be put into `` HTML elements.
    – Blake Mann Oct 24 '13 at 16:09
  • Just because you don't use `` to make a table doesn't keep it's semantic meaning, it's still wrong if you're not displaying _tabular-data_
    – Jace Cotton Oct 24 '13 at 16:16
  • 2
    But you are not making a table. You are making a three column layout (if using my previous example). And if a user was to disable their CSS, they would see the elements displayed as blocks, as would be expected. Just because an element is set to display *like* a table-cell, it does not mean it *is* a table-cell. – Blake Mann Oct 24 '13 at 16:22
  • That is true. I stand corrected. – Jace Cotton Oct 24 '13 at 16:23
  • I'm not so sure. The "semantics" of a tag mean "what it does". Using "display: table-xxx" changes that. It actually changes the semantics of the tag. Conversely, other values (none, block, inline, inline-block) change how it's laid out, but don't change what it does. To further illustrate my point, `
    ` is not semantically correct, but `
    ` is. Or, in other words, `display:table-cell` falls in the same category as `display:checkbox` (if there was such a thing).
    – Vilx- Oct 24 '13 at 17:49
  • I don't think having a table-cell styled div inside of a table element is semantically correct, nor do I see how table-cell is any different than inline-block? They both change the display behaviour, and have nothing to do with what the actual element does. Semantic HTML should basically assume that CSS does not exist, or that it was disabled. (hence the div inside the table not being semantic) CSS, on the other hand, should have no weight in semantics, as it is for visual appearance only, and does not change the HTML meaning. But semantics are a little off topic here, so let's leave it there. – Blake Mann Oct 24 '13 at 17:55
  • Hmm... I think a better word would be "functionality". Consider a checkbox. It has a very specific functionality that no amount of CSS can simulate. The same goes about a textbox, iframe, link (anchor), and many other elements. They each do their specific thing and you cannot interchange them. On the other hand, tags like div, span, p, b, and a whole lot of other really do the same thing. Their default styling might differ, but with a bit of CSS they are completely interchangeable. You might as well replace them all with a single tag and you'd have no less flexibility in your webpages. – Vilx- Oct 24 '13 at 18:20
  • And so we come to table family of tags. They too have their specific set of functionality which does not overlap with any other tag (namely, their widths and heights are linked together with other nearby tags, and a very complex specific layout engine is used for them). Except that in this case CSS for some unfathomable reason has decided that you CAN give other tags their functionality by a certain line of code. This is the part which I don't like. If you can do `display:table-cell` then it logically follows that you should also be able to do `display:iframe` etc. – Vilx- Oct 24 '13 at 18:27
  • It breaks the idea that "CSS is only for layout and does not affect functionality". – Vilx- Oct 24 '13 at 18:27