Jess McKenzie
Jess McKenzie

Reputation: 8385

Best way to structure a two column html form?

What is the best way to align the following?

I want the .inputTitle on the left and the inputInput on the right with the error inbetween them both.

CSS:

.crud_form{
    width:430px;
    margin:10px solid;
    font-family:Verdana, Geneva, sans-serif;
    background:orange;
}
.inputTitle{
    float:left;
    clear:left;
    margin:11px 10px 10px 0;
    width:95px;
    background:green;
}
.inputRequired{
    float:left;
    margin:5px;
    width:113px;
    background:blue;
}
.inputError{
    float:left;
    margin:10px;
    background:red;
}

.crud_form select textarea{
    float:left;
    clear:both;
}

HTML:

<form action="#" method="post" accept-charset="utf-8" class="crud_form" enctype="multipart/form-data">
<span class="inputTitle">First Name</span><span class="inputInput"><input type="text" name="first_name" value="" id="first_name"  /></span><span class="inputError"></span>

<span class="inputTitle">Last Name</span><span class="inputInput"><input type="text" name="last_name" value="" id="last_name"  /></span><span class="inputError"></span>

<span class="inputTitle">Address</span><span class="inputInput"><textarea name="address" cols="40" rows="10" id="address" ></textarea></span><span class="inputError"></span>

<span class="inputTitle">Phone</span><span class="inputInput"><input type="text" name="phone" value="" id="phone"  /></span><span class="inputError"></span>

<span class="inputTitle">Item</span><span class="inputInput"><select name="item" id="item">
<option value="Caps cost $15"></option>
<option value="Mugs cost $20"></option>
<option value="Childrens T-shirts, sizes 0 to 6">$10</option>
<option value="Ladies (no photo) cost $20"></option>
<option value="Men cost $20"></option>
</select></span>

<span class="inputError"></span>
<span class="inputTitle">Comments</span><span class="inputInput"><textarea name="comments" cols="40" rows="10" id="comments" ></textarea></span><span class="inputError"></span>

<input type="submit" value="Save" />

</form>

Upvotes: 5

Views: 13458

Answers (5)

Tarun
Tarun

Reputation: 1898

I don't know why everyone is using div's, span's and li's etc. It's simple, look at the example below:

label {
  width: 150px;
  padding-right: 20px;
  display: inline-block;
}
<p>
  <label for="IDofInput">text goes here</label>
  <input type="text" id="IDofInput">
</p>
<p>
  <label for="IDofInput">text goes here</label>
  <input type="text" id="IDofInput">
</p>
<p>
  <label for="IDofInput">text goes here</label>
  <input type="text" id="IDofInput">
</p>

Upvotes: 9

Eliran Malka
Eliran Malka

Reputation: 16263

Abstract

IMHO (and the W3C is backing me up), list semantics are best to describe form layouts - forms as lists of prompt data. In this presentation a grid is being used to layout the form controls.

Reference

to see a full depiction on how it's done, please refer to W3C's reference on this, originally published at the Opera developers community, on their Web Standards Curriculum.

Code Example / Implementation

HTML:

<form>
  <ul>
    <li><label for="realname">Name:</label><input type="text" name="name" value="" class="medium" id="realname" /></li>
    <li><label for="address">Email:</label><input type="text" name="email" value="" class="medium" id="address" /></li>
    <li><label for="messageBody">Comments:</label><textarea name="comments" cols="32" rows="8" class="long" id="messageBody"></textarea></li>
  </ul>
</form>

CSS:

/* base font size, other measures relay on seventh parts of this */
body {
    font-size: 14px;
    line-height: 1.714em;
}

/* form styles */
form {
    margin: 0;
    width: 35.929em;
}

/* reset list styles to be used as form layout mechanism */
ul {
    margin: 0;
    padding: 0;
    list-style-type: none;
}
li {
    clear: both;
    height: 1.714em;
    margin: 0;
}

/* form controls styles */
fieldset {
    height: 1.429em;
    margin: 0 0 -.143em 0;
    border: 0;
}
label {
    display: block;
    float: left;
    clear: left;
    width: 10.286em;
    overflow: auto;
    padding-right: 1.714em;
    text-align: right;
}
input {
    height: 1.143em;
    border: .071em solid rgb(96,96,96);
    padding: .071em;
    line-height: .929em;
}
textarea {
    height: 4.714em;
    margin-bottom: .286em;
    border: .071em solid rgb(96,96,96);
    padding: 0;
}
input,
textarea {    
    margin-top: 0;
    font-size: 100%;
    display: block;
    float: left;
    overflow: hidden;
    font-family: Futura,'Century Gothic',sans-serif;
    font-size: 1em;
}

/* input and textarea variants */
.medium {
    width: 11.714em;
}
.long {
    width: 20.429em;
}

you can play with the full code example in this jsFiddle (this does not contain the IE stylesheet).

Update

I've edited the answer to include only the relevant code for a two column layout form. please refer to the above links for a fully working example.

Upvotes: -1

Jukka K. Korpela
Jukka K. Korpela

Reputation: 201548

The best way to structure a two-column form is to use a two-column table element inside a form element. But as you say that you want “the error” (apparently, error indicator or error message) between input label (title) and input field, you actually want a three-column form, i.e. three-column table.

<form ...>
<table>
<tbody>
  <tr><td class="inputTitle"><label for="first_name">First Name</label></td>
      <td class="inputError"><span></span></td>
      <td class="inputInput"><input type="text" name="first_name" id="first_name"  /></td></tr>
</tbody>
</table>
</form>

This (apart from simulating it using CSS table features, which have limited browser support) is the only way to make browsers allocated widths to the columns, according to the width requirements of the content, instead of your making wild guesses on what might be needed.

Upvotes: 0

gcbenison
gcbenison

Reputation: 11963

To clean up the vertical alignment, you could wrap each label - input pair in a containing div, then float the inputs to the right. I am not sure based on your question if this is the alignment you are looking for, but it does have a nicer appearance.

HTML:

<form action="#" method="post" accept-charset="utf-8" class="crud_form" enctype="multipart/form-data">
  <div class="formdiv">
<span class="inputTitle">First Name</span>
<span class="inputInput">
  <input type="text" name="first_name" value="" id="first_name"  />
</span>
<span class="inputError"></span>
  </div>

  <div class="formdiv">
<span class="inputTitle">Last Name</span>
<span class="inputInput">
  <input type="text" name="last_name" value="" id="last_name"  /></span>
<span class="inputError"></span>
  </div>

  <div class="formdiv">
<span class="inputTitle">Address</span>
<span class="inputInput"><textarea name="address" cols="40" rows="10" id="address" ></textarea></span><span class="inputError"></span>
  </div>

  <div class="formdiv">
  <span class="inputTitle">Phone</span><span class="inputInput"><input type="text" name="phone" value="" id="phone"  /></span><span class="inputError"></span>
  </div>

  <div class="formdiv">
  <span class="inputTitle">Item</span><span class="inputInput"><select name="item" id="item">
  <option value="Caps cost $15"></option>
  <option value="Mugs cost $20"></option>
  <option value="Childrens T-shirts, sizes 0 to 6">$10</option>
  <option value="Ladies (no photo) cost $20"></option>
  <option value="Men cost $20"></option>
  </select></span>

  <span class="inputError"></span>
  </div>

  <div class="formdiv">
  <span class="inputTitle">Comments</span><span class="inputInput"><textarea name="comments" cols="40" rows="10" id="comments" ></textarea></span><span class="inputError"></span>
  </div>

  <input type="submit" value="Save" />

</form>

CSS:

.formdiv {
    float: left;
    width: 100%;
    margin-bottom: 1em;
}

.crud_form{
    width:430px;
    margin:10px solid;
    padding: 10px;
    font-family:Verdana, Geneva, sans-serif;
    background:orange;
}
.inputTitle {
    float:left;
    clear:left;
/*    margin:11px 10px 10px 0; */
    width:95px;
    background:green;
}

.inputInput {
    float: right;
}

.inputRequired{
    float:left;
    margin:5px;
    width:113px;
    background:blue;
}
.inputError{
    float:left;
    margin:10px;
    background:red;
}

.crud_form select textarea{
    float:left;
    clear:both;
}

Upvotes: 0

Aaron Brewer
Aaron Brewer

Reputation: 3667

I want the .inputTitle on the left and the inputInput on the right with the error inbetween them both.

The way that I have always done this was to set a width for them.

For example:

If you were to have 3 floated elements, and you wanted them to align perfectly within the "Container" per se, the Container would of course need a width set.

After you were to set the width of the Container, set the width of those 3 floated elements to equal the width of the Container.

See below:

HTML:

<div class="container">
     <div class="inputTitle"></div>
     <div class="inputError"></div>
     <div class="inputInput"></div>
     <div class="clear"></div>
</div>

CSS

.container {
   width: 600px;
}
.inputTitle {
   width: 200px;
   float: left;
}
.inputError {
   width: 200px;
   float: left;
}
.inputInput {
   width: 200px;
   float: left;
}
.clear {
   clear: both;
}

Ultimately you could add the clear: both; CSS Declaration on the Container, but I like to make a clear: both; Class just to be on the safe side.

Of course you can always use Labels, but setting a pre-defined width for a label via CSS would apply to all Labels, within a class and or id.

I hope that helps! Thanks! Aaron

Upvotes: 0

Related Questions