11

I'm aware that there are already a bunch of questions about form layout using CSS versus Tables. On the whole, I think CSS is the way to go, but all the CSS solutions I've seen have the drawback of "hard coding" the width of the labels and/or input fields.

The result is that one or two custom rules needs to be added for each form, assuming that the maximum width of the labels are different in each case.

Is there a way that I can style forms, such that it will automagically line up the labels and inputs regardless of how long the labels are?

4
  • 2
    +1: This one always bugs me as well. So far I've had to hardcode the size every time. Commented Feb 1, 2010 at 4:43
  • 1
    If you make a truly tabular layout there's nothing wrong using <table>. Commented Feb 1, 2010 at 13:23
  • 1
    @KennyTM - a tabular layout or not. Tables should be used for tablular data, not layout. The author of the question even acknowledges this. Commented Feb 1, 2010 at 13:30
  • 1
    When you've got what is primarily a data input application (dozens of fields per page) translated in languages that are terse and verbose, not fixing the widths is important. P.S. Gmail's settings page uses tables. Commented Feb 22, 2010 at 21:31

5 Answers 5

8

Have a look at the form on the left handside at this URL http://www.blueprintcss.org/tests/parts/forms.html

If you place label on 1 line and the input box on another line then you don't have to worry about the alignment of labels. Style it a bit more you will have a clean and nice web2.0 like form

enter image description here

Cheers

Sign up to request clarification or add additional context in comments.

2 Comments

+1 for this. If you will have a very long label in one field, a short one in other, then making it to be 2 column will be ugly, even if you use table. Make it 2 line, label in line 1, form field in line 2. You will not need to worry about label length anymore.
None of those layouts are comparable.
1

Personal opinion: use a table.

Every time you write something like

label {
    width: 150px; /* or whatever width */
}

then you are mixing content and presentation because the value of the label can only be calculated if you know what it will contain, which goes against the principles of the semantic-CSS purists.

2 Comments

That is completely incorrect. When you use a table you are mixing content with presentation. The entire reason we have CSS is to separate this. Hence the layout is controlled by specifying the width in the CSS file. If you use a table. The layout is controlled by the table element now embedded in your content.
I didn't say it isn't so. I said that even with a styled label tag you're mixing content with presentation. CSS definitions should not depend on what a field contains, but they do in this case. So you just might as well use a table which works reliably in all browsers, does what the OP wants and just in a few lines of code. Tables could be abandoned if CSS offered alternatives for all needs working in all browsers without silly hacks.
0

Well the subject of placing a label above or adjacent to the input is a separate discussion (I recommend reading Luke Wroblewski's book on the subject: http://www.lukew.com/resources/articles/web_forms.html)

Styling web forms is quite trivial. First off you want to ensure you are marking up your forms in a semantically appropriate manner. This is one of the main advantages allowed to you now that you are using CSS for layout instead of tables. For more on this see the excellent List Apart Article on the subject: http://www.alistapart.com/articles/prettyaccessibleforms/

Now in the aforementioned article the author uses a display property called inline-block. This is a rather simple way of achieving the affect. Simply apply:

label {
   display: inline-block;
   width: 120px; /* Specify the width that works for your design */
}

And your labels will have a fixed length with the input adjacent to them. However, if you do not specify the width and just use:

label, input {
   display: inline-block;
}

Then your labels and inputs will both line up inline 'automagically' as you put it. The problem here is not a technical issue but rather a design issue. If you're inputs to not line up vertically then it will make it more difficult for a user to complete your form. This is another consideration you should keep in mind as it's easier to position the label and input in this manner than it is to accommodate for fixed widths.

Another issue is that inline-block doesn't work well in certain browsers. Inline-block is not reliable in older versions of Firefox or IE. So I tend to use an alternative method. Let's say you mark up your forms in a semantically appropriate way using a list. Well in that case you could have something like:

<form>
  <fieldset>
    <legend>Health information:</legend>
    <ul>
      <li><label>Height</label> <input type="text" size="3" /></li>
      <li><label>Weight</label> <input type="text" size="3" /></li>
    </ul>
  </fieldset>
</form>

In this case we can use a fixed width and absolute positioning to line up our elements adjacently:

form li {
  display: block;
  padding: 2px;
  position: relative;
}

/* The top and left position of 2px simulate 
   padding since we are using absolute positioning. */
form label {
  display: block;
  left: 2px;
  position: absolute;
  top: 2px;
  width: 120px;
}

form input {
  display: block;
  margin-left: 125px;
}

The label is positioned relative to the list item and the input is pushed over to the side with a left margin. There is an issue with this method though. This method will only work with a hardcoded width. More importantly, a multiline label won't clear properly. So in this situation we can take a similar approach but use floats and overflow. So we could use this alternative CSS on the same html markup I showed earlier:

form li {
  display: block;
  overflow: hidden; /* This clears the floating element. */
  padding: 2px;
}

form label {
  display: block;
  float: left;
  padding-right: 5px;
}

form input {
  display: block;
}

Now with this method the label is floated to the left of the input. If you do not specify a width the label will be as wide of the contents that reside in it (up to the point of the width of it's parent node in the HTML document). By setting overflow to hidden on the parent object there is no need to clear the element. This technique will work with a hardcoded width or the inherited default which is width: auto.

Last but not least if you want to use the most efficient form approach (labels on top of the inputs), which has proven to be the style of form that users can complete the fastest, the only css you need in order to accomplish this is:

label, input {
  display: block;
}

One other note - with marking up your HTML as such you might be wondering about all of those list elements creating bullet points etc. You should opt for including a CSS reset in your document to ensure consistency amongst browsers. I recommend Eric Meyer's:

http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/

7 Comments

The question specifically asks for solutions where the labels are of arbitrary length. This does not address that concern in any way.
The methods posted albeit one do what the question asks if you omit the rule for width. I've now explained this in the solution whilst also providing all three popular methods for achieving this style of layout with CSS and HTML. Additionally the answer points considerations the designer should take when designing forms in such a manner. Additionally, it references proper methods for marking up web forms in semantically appropriate HTML as the question mentioned they are transitioning from table based layouts.
"Styling web forms is quite trivial" Given the size of the code posted this doesn't look trivial.
Yes it is. It's really fairly simple. In this post I've explained four different approaches to do it.
I'm sorry I must be doing something wrong then: I'm trying your markup with your only style rules not involving a label with fixed width, and input boxes are not aligned at all.
|
0

You can handle this by floating the labels and placing them in a floating block element, and similarly for the input fields. This will create a two column layout that automatically resizes based on the contents. Here's the HTML:

<form>
    <div id='labels'>
        <div>Name: </div>
        <div>Street:</div>
        <div>This is a longer than usual label:</div>
        <div>City:</div>
    </div>

    <div id='inputs'>
        <div><input type="text"></div>
        <div><input type="text"></div>
        <div><input type="text"></div>
        <div><input type="text"></div>
    </div>

</form>

And here are the CSS rules:

#labels {
    float: left;
}

#labels div {
    clear: left;
    float: left;
}

#inputs {
    float: left;
}

#inputs div {
    clear: left;
    float: left;
}

#labels div, #inputs div {
    height: 30px;
}

EDIT: If you want to create a semantic connection between labels and inputs, you can formally tag each label as an html label and then use the for and id attributes to link them. For example, here's a label definition:

<div><label for='name'>Name: </div>

and here is the corresponding input field:

<div><input id='name' type="text"></div>

3 Comments

I'm sorry but this doesn't keep any connection between labels and their values. They are in completely separated divs and their only link is visual if you happen to place them side by side. There is no "semantic" connection and the meaning of your content stricly depends on its presentation. Aligning them is trivial, the point is align them in a meaningful way.
This is easily solved, and I've edited the answer accordingly.
This is a small nitpick, but the baseline of the label and the inputs do not line up in ie6.
-1

There's nothing wrong with having rules for that specific page embedded in the page header, instead of having different files for everything.

If your forms are so different that you say they are, then there's no other way to do it than to make custom rules for each...

Whether or not you want to put all form styles in a huge file, or just include in the page header those that are relevant, depends on how many forms your users will access on an average visit. A few forms per visit; put them in the header. A lot of forms per average visit; put them all in a separate file so it can be cached by the user.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.