12

[Meta-note:] I was browsing the question page, getting really tired of "DIVS vs Tables" "When to use tables vs DIVS" "Are Divs better than Tables" "Tables versus CSS" and all the questions that ask THE SAME THING OMG PEOPLE but I would like to see all the ways people tackle the translation of the canonical example of "why you should give up and use tables":

<table>
  <tr>
    <td> Name </td>
    <td> <input> </td>
  </tr>
  <tr>
    <td> Social Security Number </td>
    <td> <input> </td>
  </tr>
</table>

Question: How to best (semantically, simply, robustly, fluidly, portably) implement the above without tables. For starters, I guess a naive implementation uses a fixed column width for the first column, but that can have iffy results for dynamically generated content. Including strengths/weaknesses of your approach in the answer would be nice.

P.S. Another one I wonder about a lot is vertical centering but the hack for that is covered pretty well at jakpsatweb.cz

EDIT: scunlife brings up a good example of why I didn't think out the problem that carefully. Tables can align multiple columns simultaneously. The Question still stands (I'd like to see different CSS techniques used for alignment/layout) - although solutions that can handle his? more involved example definitely are preferred.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Jimmy
  • 89,068
  • 17
  • 119
  • 137

5 Answers5

11

What I usually do is :

<form>
 <label for="param_1">Param 1</label>
 <input id="param_1" name="param_1"><br />
 <label for="param_2">Param 2</label>
 <input id="param_2" name="param_2"><br />
</form>

and in a CSS :

label,input { display: block; float: left; margin-bottom: 1ex; }
input { width: 20em; }
label { text-align: right; width: 15em; padding-right: 2em; }
br { clear: left; }

Of course, you'll have to define the width according to your actual data :-)

  • First, give label and input display: block, so that it can be assigned a size and be lined up.
  • They both get float: left because Explorer does things a bit differently
  • Format the label nicely
  • hack the br so that there's a clear: left somewhere, and I remember that putting it on the label didn't work on some browser.

Plus, with the br you get a nice formatting even if the browser does not support CSS :-)

mat
  • 12,943
  • 5
  • 39
  • 44
  • This is indeed what I thought of first, its pretty clean and understandable. I was hoping there would be other solutions that could allow for a dynamic column width for the left column – Jimmy Dec 04 '08 at 00:31
  • Well, if you want dynamic column width, you have to do your boxes the other way around, that is, all the labels, and all the inputs, and there, you will certainly loose horizontal alignment :-) – mat Dec 04 '08 at 00:43
  • suppose you use 'white-space:nowrap' and specified line-height? could you get away with it? – Jimmy Dec 04 '08 at 00:47
  • oh wait, yeah, then you lose vertical fluidity. hmm. – Jimmy Dec 04 '08 at 00:56
  • well, you could get away with almost everything :-) The problem here would be that, hum, you have no way of knowing 1) the right line height, 2) if some browser won't have the idea of rendering it differently, and 3) what will it do without CSS as it would destroy the "normal" flow of the document. – mat Dec 04 '08 at 00:57
  • 4
    a no-no to the br tag. with this layout you could just have said label { clear:left } – Steve Perks Dec 29 '08 at 17:29
  • Supporting Steve. Also, don't forget `fieldsets` , as they are extremely useful for complex, yet meaningful layouts. – Esteban Küber Jul 24 '09 at 16:46
  • @StevePerks as I said, the br is there in the case the browser does not support css, like a text based brower. – mat Apr 06 '12 at 15:23
  • @mat - I agree with the rationale for using
    , but it's use in this place is still presentational rather than structural. If each pairing/grouping is within a block level container, the inclusion of the
    is not needed.
    – Steve Perks May 14 '12 at 18:49
5

The trick is when the form gets more complicated than your sample, you realize that tables enable a "flexible grid" that no other elements do.

e.g. what if the "input" is more complicated than a text box? e.g. a bunch of radio buttons, each with their own label:

Color: [____Red___][v]
 Hood: [*] 
 Size: (_) Small
       (_) Medium
       (_) Large
       (*) X-Large

If all you need are simple forms, CSS is great, but as soon as you need a grid, things get interesting...

If you really want to do this, I would check out The Man In Blue's Solution, it works pretty well and is very clean.

scunliffe
  • 62,582
  • 25
  • 126
  • 161
3

People talk about tables getting their forms to display the way they want, that's true, ONLY if you want to display your forms in columns and are willing to lose semantic meaning. With the following HTML in place, it's possible to display this form in as many layouts as you might wish.

BTW - No to the <br />

<form>
 <fieldset>
  <legend>Personal Info</fieldset>
  <div>
   <label for="name">Name</label>
   <input id="name" name="name" />
  </div>
  <div>
   <label for="ssn">Social Security Number</label>
   <input id="ssn" name="ssn" />
  </div>
 </fieldset>
</form>

You can clear the <divs> or set them to overflow: hidden to ensure that the floats are cleared.

Options from the above html:

Name |==============|    SSN |==============|

Name |==============|
SSN |==============|

Name     |==============|
SSN      |==============|

    Name |==============|
     SSN |==============|

   Name: |==============|
    SSN: |==============|

Name:
|==============|
SSN:
|==============|

All of the above can be accomplished with just a few lines of css.

When it comes to radio, checkboxes, and submit buttons it gets a little more complicated, but clean semantic HTML CAN be displayed the way you want it using css.

Steve Perks
  • 5,490
  • 3
  • 28
  • 41
3

Although the other suggestions are probably better for getting a flexible layout, the literal answer to the question is something like:

<form action="www.example.com">
    <div class="table">
        <div class="tbody">
          <div class="tr">
            <div class="td"> <label for="name">Name</label> </div>
            <div class="td"> <input id="name"> </div>
          </div>
          <div class="tr">
            <div class="td"> <label for="ssn">Social Security Number</label> </div>
            <div class="td"> <input id="ssn"> </div>
          </div>
        </div>
    </div>
</form>

with

    <style type="text/css">
        div.table { display:table; border-spacing:2px; }
        div.tbody { display:table-row-group; }
        div.tr { display:table-row; }
        div.td { display:table-cell; vertical-align: middle; padding:1px; }
    </style>

This works with the latest versions of Firefox, Chrome, Opera, and Safari. It also works with IE8 Beta 2 (standards mode). It doesn't work with IE7 or earlier, but "progressive enhancement" and all that.

Alohci
  • 78,296
  • 16
  • 112
  • 156
  • Shame rowspan and colspan don't work (I just tried in Firefox 3.0.6) – finnw Feb 18 '09 at 17:53
  • I agree this is the solution, I just don't understand why anyone would do this. The only difference is that your essentially using classes to link your css and html instead of html type (i.e. your using class="table" rather than form.table{} in in the css). I am currently starting to refactoring 50k lines code and most of my dialog forms (40+) use a table to line up the inputs, labels and special controls; this table is usually inside a div. I'm trying to desperately to determine why I should change to this method... but alas I'm coming up way short. – gunslingor Oct 18 '16 at 23:30
  • @gunslingor - You wouldn't, at least not quite like that. The class names in particular are chosen to demonstrate the layout principle, whereas in production code you should be using class names that describe the content, not the layout. The point is that sometimes you want a layout of columns and rows, but you don't semantically have tabular data. CSS tables provide a means of delivering that. Moreover, understanding CSS tables, and particularly how anonymous table objects are generated leads to some very convenient layout effects for very little markup. – Alohci Oct 19 '16 at 00:14
0

I was thinking of something like:

<div style="text-align:right; float:left;">
    Name: <input /> <br />
    Social Security Number: <input /> <br />
</div>

which, if the right column is fixed-length, aligns OK with variable text length, but I wonder what are the disadvantages of this method?

Jimmy
  • 89,068
  • 17
  • 119
  • 137