tags:

views:

1397

answers:

8

I want the following layout to appear on the screen:

FieldName 1             [Field input 1]
FieldName 2 is longer   [Field input 2]
    .                         .
    .                         .
FieldName N             [Field input N]

Requirements:

  • Field names and field inputs must align on the left edges
  • Both columns must dynamically size themselves to their content
  • Must work cross-browsers

I find this layout extremely simple to do using HTML tables, but since I see a lot of CSS purists insisting that tables only be used for tabular data I figured I'd find out if there was a way to do it using CSS.

A: 

What's wrong with keeping tabular data in a table?

brianng
Nothing, but the debate is whether labels/fields are tabular **data.**
SoloBold
i agree that is the debate, given the fieldset, labels, etc tags xhml seems to be leaning toward they are not data but input areas and should not be layed out as such... but i know that is still debatable
ethyreal
A: 

FieldName objects should be contained in SPANs with style attributes of float: left and a width that is wide enough for your labels.

Inputs should be contained within a span styled to float: left. Place a <div style="clear: both"/> or <br/> after each field input to break the floating.

You may enclose the aforementioned objects into a div with the width style attribute set that is wide enough for both labels and inputs, so that the "table" stays small and contained.

Example:

<span style="float: left; width: 200px">FieldName1</span><span style="float: left"><input/><br/>

<span style="float: left; width: 200px">FieldName2</span><span style="float: left"><input/><br/>

<span style="float: left">FieldName3</span><span style="float: left"><input/><br/>

Hector Ramos
I believe he would want a "div" to be present after each input fields with 'clear:both' as the style.
Adhip Gupta
A: 

Each row is to be taken as a 'div' that contains two 'spans' one for fieldname and one for the input. Set 'float:left' on both the spans. However, you need to set some width for the 'fieldname' span.

Also, style the div to include the attribute 'clear:both' for precaution.

Adhip Gupta
+3  A: 

better still use a list

     <fieldset class="classname">
  <ul>
   <li>
    <label>Title:</label>
    <input type="text" name="title" value="" />
   </li>
        </ul>
     </fieldset>

the set the li tags width wide enough for both label and input and float the label to the left.

also to achieve that table like block with the tables you could set the label width to be as big as the largest fieldname forcing all the labels or expand that wide.

[edit] this is some good reading on a list apart

ethyreal
I guess the tag-selector "ul li label" will have to have a explicit width set to make it appear as a table.
Adhip Gupta
correct, you may need to through the input into its own box like a p to get the layout floating right in all browsers
ethyreal
A List Apart is a great site, I recommend it heavily!I've also used this article in the past:http://www.websiteoptimization.com/speed/tweak/forms/
Eric Lathrop
The label is only linked to the input box if it either used a 'for' attribute or contained the input box. Also, when a label is linked to the input box, the list isn't really required - the form, fieldset, label and input have enough semantic meaning.
Daniel James
+10  A: 

I wouldn't, I would use a table. This is a classic example of a tabular layout - exactly the sort of thing tables are supposed to be used for.

Nick Johnson
I disagree, in my opinion tables should only be used for tabular data, not tabular layouts; there's quite a difference.
conmulligan
If it's TABular, it's suitable for a TABle. The only difference between this and "tabular data" is that the right hand column consists of input boxes. Trying to shoehorn something else in here is just silly.
Nick Johnson
+1  A: 

It's not clear that it is tabular data as some others have commented, though it could be. A table would imply a semantic relationship between all the items in the respective columns (other than just "they're all names of database columns"). Anyway, here's how I've done it before:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title>Form layout</title>
    <style type="text/css">
        fieldset {width: 60%; margin: 0 auto;}
        div.row {clear: both;}
        div.row label {float: left; width: 60%;}
        div.row span {float: right; width: 35%;}
    </style>
</head>
<body>
    <form action="#" method="post">
        <fieldset>
            <legend>Section one</legend>
            <div class="row">
                <label for="first-field">The first field</label>
                <span><input type="text" id="first-field" size="15" /></span>
            </div>
            <div class="row">
                <label for="second-field">The second field with a longer label</label>
                <span><input type="text" id="second-field" size="10" /></span>
            </div>
            <div class="row">
                <label for="third-field">The third field</label>
                <span><input type="text" id="third-field" size="5" /></span>
            </div>
            <div class="row">
                <input type="submit" value="Go" />
            </div>
        </fieldset>
    </form>
</body>
</html>

Edit: Seems that 'by design' I can't reply to comments on my answer, obviously this is somehow less confusing. So, in reply to 17 of 26's comment - the 60% width is entirely optional, by default the fieldset will inherit the width of the containing element. You could also, of course, make use of min-width and max-width, or any of the table layout rules, if only IE supported them, but that's not CSS failing miserably ;)

robertc
The flaw with this is that the layout does not size itself to the data, which is one of my requirements. It's a percentage of the screensize, which can get really wide on wide screen resolutions. In my opinion, dynamic layouts is where CSS fails miserably.
17 of 26
Ugh. Too many divs and spans, too much markup with empty semantic meaning.
Jonathan Arkell
@Jonathan: Exactly. This sacrifices clean, meaningful markup for obscure markup in the name of not using tables for something that's obviously well suited to them.
Nick Johnson
+5  A: 

I think most of the answers are missing the point that the original questioner wanted the columns widths to depend on the width of the content. I believe the only way to do this with pure CSS is by using 'display: table', 'display: table-row' and 'display: table-cell', but that isn't supported by IE. But I'm not sure that this property is desirable, I find that creating a wide columns because there is a single long field name makes the layout less aesthetically pleasing and harder to use. Wrapped lines are fine in my opinion, so I think the answers that I just suggested were incorrect are probably the way to go.

Robertc's example is ideal but if you really must use tables, I think you can make it a little more 'semantic' by using <th> for the field names. I'm not sure about this so please someone correct me if I'm wrong.

<table>
    <tr><th scope="row"><label for="field1">FieldName 1</label></th>
        <td><input id="field1" name="field1"></td></tr>
    <tr><th scope="row"><label for="field2">FieldName 2 is longer</label></th>
        <td><input id="field2" name="field2"></td></tr>
    <!-- ....... -->
</table>

Update: I haven't been following this closely, but IE8 apparently supports CSS tables, so some are suggesting that we should start using them. There's an article on 24 ways which contains a relevant example at the end.

Daniel James
I agree, if you had one field name that was a _lot_ longer, it would get ugly. The trick is to use shorter field names and then include tooltips if the short name doesn't describe the field well enough.
17 of 26
But then you could make sure the column is wide enough by giving it a large enough width in ems, and still have it look reasonable. Right align the labels if they're too far from the input boxes.
Daniel James
The markup you provide there looks ideal to me. This _is_ a tabular layout, and your example adds in the relevant labels etc.
Nick Johnson
You believe wrong, Sir. Take a look at my answer.
roosteronacid
+2  A: 

This markup and CSS roughly achieves your stated goals under the restrictions for this question...

The Proposal

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title>My Form</title>
    <style type="text/css">
        #frm1 div {float: left;}
        #frm1 div.go {clear: both; }
        #frm1 label, #frm1 input { float: left; clear: left; }
    </style>
</head>
<body>
    <form id="frm1" action="#" method="post">
        <fieldset>
            <legend>Section One</legend>
            <div>
               <label for="field1">Name</label>
               <label for="field2">Address, City, State, Zip</label>
               <label for="field3">Country</label>
            </div>
            <div>
               <input type="text" id="field1" size="15" />
               <input type="text" id="field2" size="20" />
               <input type="text" id="field3" size="10" />
            </div>
            <div class="go">
                <input type="submit" value="Go" />
            </div>
        </fieldset>
    </form>
</body>
</html>

The Merits

...but I would not recommend its use. The problems with this solution are

  1. the very annoying entire-column wrap at skinny browser widths
  2. it separates the labels from their associated input fields in the markup

The solution above should be (I haven't verified this) accessible-friendly because screen readers, I have read, do a good job of using the for="" attribute in associating labels to input fields. So visually and accessibly-wise this works, but you might not like listing all your labels separately from your input fields.

Conclusion

The question as it is crafted -- specifically the requirement to automatically size the width of an entire column of different-length labels to the largest label length -- biases the markup solution towards tables. Absent that requirement, there are several great semantic solutions to presenting forms, as has been mentioned and suggested by others in this thread.

My point is this: There are several ways to present forms and collect user input in a pleasing, accessible, and intuitive way. If you can find no CSS layout that can meet your minimum requirements but tables can, then use tables.

Carl Camera
Hmmm, a near-immediate down-vote without comment. Folks, I call 'em like I see 'em.
Carl Camera