Reputation: 1818
I'm building a bunch of forms that have labels and corresponding fields (input element or more complex elements).
Labels go on the left, fields go on the right. Labels in a given form should all be a specific width so that the fields all line up vertically.
There are two ways (maybe more?) of achieving this:
Rows: Float each label and each field left. Put each label and field in a field-row div/container. Set label width to some specific number. With this approach labels on different forms will have different widths, because they'll depend on the width of the text in the longest label.
Columns: Put all labels in one div/container that's floated left, put all fields in another floated left container with padding-left set. This way the labels and even the label container don't need to have their widths set, because the column layout and the padding-left will uniformly take care of vertically lining up all the fields.
So approach #2 seems to be easier to implement (because the widths don't need to be set all the time), but I think it's also less object oriented, because a label and a field that goes with that label are not grouped together, as they are in approach #1. Also, if building forms dynamically, approach #2 doesn't work as well with functions like addRow(label, field)
, since it would have to know about the label and the field containers, instead of just creating/adding one field-row element.
Which approach do you think is better? Is there another, better approach than these two?
Upvotes: 4
Views: 17690
Reputation: 35995
Approach #1 is the far better for a number of reasons, mainly pertaining to flexibility and the other points mentioned by Kevin Boucher, plus your own points with regard to dynamic creation.
I wouldn't recommend not having containing elements - even though it is nicely possible - you deny yourself a lot of extra power with regards to padding, positioning and overflow handling. It also makes dynamic creation more tricky.
Your arguments for going with approach #2 also need not be a benefit either, considering you can set one width for your label container in your css - via a class - and this can easily be changed or designed to be responsive. Basically meaning you only have one place again to change your label dimensions.
Also With #2, whilst making your horizontal label layout more automatic - vertical layout would become more manual and tricky considering you would have to give your label and field containers the same height in order to line up (as they couldn't rely on a mutal parent). I'd make a guess that you'll have more rows than columns so this would just add work ;)
css:
.field-row {
overflow: hidden;
}
.field-row label {
display: block;
width: 30%;
float: left;
}
.field-row .field-container {
width: 70%;
float: left;
}
markup:
<div class="field-row">
<label>Label Text</label>
<div class="field-container">
<input type="text" />
</div>
</div>
I'd probably go for the above myself as that would cover most of what I've ever needed, however if you wanted more control with regard to possible future changes that might occur in your app, you could do the following:
css 2:
.field-row {
overflow: hidden;
}
.field-row .label-container {
width: 30%;
float: left;
}
.field-row .field-container {
width: 70%;
float: left;
}
markup 2:
<div class="field-row">
<div class="label-container"><label>Label Text</label></div>
<div class="field-container">
<input type="text" />
</div>
</div>
By just adding one extra wrapper you then allow for the ability of more complicated labels (i.e. hiding the text and replacing with images, or adding explanatory text with js) - you also give yourself more control with regards to center or right alignment.
Anyway just my thoughts :)
Upvotes: 3
Reputation: 41865
Rows approach using only div's. jsFiddle here: http://jsfiddle.net/v7R8j/1/
HTML:
<form>
<div class="label">Type text:</div>
<div class="field"><input type="text"/></div>
<div class="clear"></div>
<!-- ... -->
<div class="label">Submit button:</div>
<div class="field"><input type="submit"/></div>
<div class="clear"></div>
</form>
CSS:
.label {
width: 150px;
}
.field, .label {
float: left;
border: 1px solid orange;
padding: 4px;
margin: 4px;
}
.clear {
clear:both;
}
Upvotes: 0
Reputation: 13843
Neither. Do it with CSS - containing divs are unnecessary. For example:
<style>
form { width: 28em; margin: 5px; padding: 5px; border: solid #000 1px; }
label { width: 6em; float: left; text-align: right; margin: .5em 1em; clear: both; border: dashed #666 1px; }
input, textarea { margin: .5em 0; width: 17em; }
</style>
<form>
<label for="first">First Name:</label>
<input type="text" name="first_name" id="first" size="20" maxlength="50" />
<label for="last">Last:</label>
<input type="text" name="last_name" id="last" size="20" maxlength="50" />
</form>
Upvotes: 2