<p>While they may not be that pretty, forms are one of the most important parts of a web site. <a href="//trevor-davis.com/blog/tutorial/css-forms/">I have already written an article on CSS Forms</a>, that was over a year ago, and I have developed much better techniques.</p>

<p>There are other <a href="http://www.lukew.com/resources/articles/web_forms.html">great resources for information about form design</a>, and I will take this information into account when I am showing the flexibility of my method of marking up and styling forms.</p>

<h2>The Markup</h2>
<p>After previously using a <strong>definition list</strong> to mark up my forms, I have switched to using an <strong>ordered list</strong> now. I switched for two main reasons:</p>

<ul><li>The list item of the ordered list provides a containing clearing element that the definition list does not provide.</li>
<li>Semantically, it just makes more sense. A form is really just a list of form fields to fill out. Forms are typically meant to be filled out in order, hence the ordered list instead of un-ordered list (I think this could be debated, but in the long run, either one is more semantic than anything else).</li>
</ul><p>I have decided to create just a <a href="//assets.trevor-davis.com/play/forms-revisited/">simple un-styled form</a> to use as an example. Here is what the markup of the page is:</p>
<div class="codeblock"><code>
&lt;ol class="forms"&gt;<br /> &lt;li&gt;&lt;label for="name"&gt;Name&lt;/label&gt;&lt;input type="text"name="name" id="name" /&gt;&lt;/li&gt;<br /> &lt;li&gt;&lt;label for="email"&gt;Email&lt;/label&gt;&lt;input type="text" name="email" id="email" /&gt;&lt;/li&gt;<br /> &lt;li&gt;&lt;label for="city"&gt;City&lt;/label&gt;&lt;input type="text" name="city" id="city" /&gt;&lt;/li&gt;<br /> &lt;li&gt;&lt;label for="state"&gt;State&lt;/label&gt;&lt;input type="text" name="state" id="state" /&gt;&lt;/li&gt;<br /> &lt;li&gt;&lt;label for="zip"&gt;Zip&lt;/label&gt;&lt;input type="text" name="zip" id="zip" /&gt;&lt;/li&gt;<br /> &lt;li class="grouping"&gt;&lt;label&gt;Sign Up for the Following&lt;/label&gt;<br />  &lt;ul&gt;<br />   &lt;li&gt;&lt;input type="checkbox" name="info1" id="info1" /&gt;&lt;label for="info1"&gt;Information 1&lt;/label&gt;&lt;/li&gt;<br />   &lt;li&gt;&lt;input type="checkbox" name="info2" id="info2" /&gt;&lt;label for="info2"&gt;Information 2&lt;/label&gt;&lt;/li&gt;<br />   &lt;li&gt;&lt;input type="checkbox" name="info3" id="info3" /&gt;&lt;label for="info3"&gt;Information 3&lt;/label&gt;&lt;/li&gt;<br />  &lt;/ul&gt;<br /> &lt;/li&gt;<br /> &lt;li&gt;&lt;label for="message"&gt;Message&lt;/label&gt;&lt;textarea name="message" id="message"&gt;&lt;/textarea&gt;&lt;/li&gt;<br /> &lt;li class="buttons"&gt;&lt;button type="submit" name="submit" id="submit"&gt;Submit&lt;/button&gt;&lt;/li&gt;<br />&lt;/ol&gt; 

</code></div>

<p>Even without any style applied, the form is still completely usable.</p>

<h2>Styling the Forms</h2>
<p>There are really 3 main styles of laying out forms:</p>
<ul><li>Labels above the form field</li>
<li>Labels to the side of the form field, jagged right</li>
<li>Labels to the side of the form field, jagged left</li>
</ul><p>Again, like I said, I am not going to go through the pros and cons of each method, I am going to show how easy it is to switch between the methods using my markup.</p>

<h3>Labels Above the Form Field</h3>
<p>This is by far the easiest method. Here is the CSS used to style my <a href="//assets.trevor-davis.com/play/forms-revisited/forms-styled-labels-stacked/">example form</a>:</p>

<div class="codeblock"><code>
ol.forms { float: left; list-style: none; width: 100%; }<br />ol.forms li { <br /> clear: both; <br /> float: left; <br /> margin: 0 0 10px; <br /> width: 100%; <br />}<br />ol.forms label { cursor: pointer; display: block; font-weight: bold; }<br />ol.forms input, ol.forms textarea { <br /> font: inherit;<br /> padding: 2px;<br /> width: 300px;<br />}<br />ol.forms textarea { height: 250px; }<br />ol.forms li.grouping { margin-bottom: 0; }<br />ol.forms li.grouping ul { list-style: none; }<br />ol.forms li.grouping ul label { <br /> display: inline;<br /> font-weight: normal;<br /> margin: 0 0 0 10px;<br />}<br />ol.forms li.grouping ul input { width: auto; } 

</code></div>

<p>Really nothing too complicated. In my opinion, I don’t like stacking the label over the form field; I think it just makes the form too long.</p>

<h3>Labels to the Side of the Form Field, Jagged Right</h3>
<p>I like this layout of forms the best. I think it presents the form in a clear way so that you can just scan right through the form fields. With just a few changes to the CSS, you can float the labels to the left of the form fields. The changes are marked in bold:</p>

<div class="codeblock"><code>
ol.forms { float: left; list-style: none; width: 100%; }<br />ol.forms li { <br /> clear: both;<br /> float: left;<br /> margin: 0 0 10px;<br /> width: 100%;<br />}<br />ol.forms label { <br /> cursor: pointer;<br /> display: block;<br /> &lt;strong&gt;float: left;&lt;/strong&gt;<br /> font-weight: bold;<br /> &lt;strong&gt;margin: 0 10px 0 0;<br /> width: 90px;&lt;/strong&gt;<br />}<br />ol.forms input, ol.forms textarea { <br /> font: inherit;<br /> padding: 2px;<br /> width: 300px;<br />}<br />ol.forms textarea { height: 250px; }<br />&lt;strong&gt;ol.forms li.grouping label { margin: 0; width: auto; }&lt;/strong&gt;<br />ol.forms li.grouping { margin-bottom: 0; }<br />ol.forms li.grouping ul { list-style: none; &lt;strong&gt;margin-left: 100px;&lt;/strong&gt; }<br />ol.forms li.grouping ul label { <br /> display: inline;<br /> &lt;strong&gt;float: none;&lt;/strong&gt;<br /> font-weight: normal;<br /> margin: 0 0 0 10px;<br /> &lt;strong&gt;width: auto;&lt;/strong&gt;<br />}<br />ol.forms li.grouping ul input { width: auto; }<br />&lt;strong&gt;ol.forms li.buttons { float: none; margin-left: 100px; width: auto; }&lt;/strong&gt; 

</code></div>

<p><a href="//assets.trevor-davis.com/play/forms-revisited/forms-styled-labels-left/">Take a look at the example with the fields on the left</a>. Depending upon your label length, you may need to increase the width of the labels so that it does not span more than one line, but that is an easy enough change.</p>

<h3>Labels to the Side of the Form Field, Jagged Left</h3>
<p>Now with two changes to the CSS, you can easily switch to having the labels jagged left, which puts them closer to the form input. The changes needed are highlighted in bold:</p>

<div class="codeblock"><code>
ol.forms label { <br /> cursor: pointer;<br /> display: block;<br /> float: left;<br /> font-weight: bold;<br /> margin: 0 10px 0 0;<br /> &lt;strong&gt;text-align: right;&lt;/strong&gt;<br /> width: 90px;<br />}<br />ol.forms li.grouping label { margin: 0; &lt;strong&gt;text-align: left;&lt;/strong&gt; width: auto; } 

</code></div>

<p><a href="//assets.trevor-davis.com/play/forms-revisited/forms-styled-labels-right/">Here is the example of the form with the labels jagged left</a>.</p>

<h3>Taking it a Step Further with More CSS and a Little jQuery</h3>
<p>Since I like the form layout with labels to the side and jagged right, I am going to use <a href="//assets.trevor-davis.com/play/forms-revisited/forms-styled-labels-left/">this one</a> to customize the display a little, and then add in some jQuery functionality.</p>

<h4>Improving the Display</h4>
<p>When looking at the form, it may be confusing to have all form fields be the same width. It is helpful to the user to modify the width to suit the data that will be entered.</p>

<p>For example, there is no reason that the zip code, city, and state fields should be so long, so let’s add a class to each one to shorten it to the length of the data that will probably be entered. Here is the modified markup:</p>

<div class="codeblock"><code>
&lt;li&gt;<br /> &lt;label for="city"&gt;City&lt;/label&gt;<br /> &lt;input type="text" name="city" id="city" class="medium" /&gt;<br />&lt;/li&gt;<br />&lt;li&gt;<br /> &lt;label for="state"&gt;State&lt;/label&gt;<br /> &lt;input type="text" name="state" id="state" class="small" /&gt;<br />&lt;/li&gt;<br />&lt;li&gt;<br /> &lt;label for="zip"&gt;Zip&lt;/label&gt;<br /> &lt;input type="text" name="zip" id="zip" class="extraSmall" /&gt;<br />&lt;/li&gt; 

</code></div>

<p>Then we just have to add those 3 classes to the CSS:</p>

<div class="codeblock"><code>
ol.forms .extraSmall { width: 50px; }<br />ol.forms .small { width: 100px; }<br />ol.forms .medium { width: 150px; } 

</code></div>

<p>Here is what <a href="//assets.trevor-davis.com/play/forms-revisited/forms-styled-labels-left-customized-more/">the form looks like with that little bit of extra style</a>. I also added in some help text, a notation for required fields, and the associated CSS; so take a look at the code to see that.</p>

<h4>Adding a Little jQuery</h4>
<p>Obviously you have read my article about <a href="//trevor-davis.com/blog/tutorial/ajax-forms-with-jquery/">AJAX forms with jQuery</a>, which discusses how to add AJAX functionality to a form in a degradable way. So the following code assumes that you are going to be doing server side validation of the form as well.</p>

<p>Since there are required fields in this form, I add a class of <strong>required</strong> to the form and to each parent list item of required input fields.</p>

<p>First, we want our JavaScript to execute when the form with a class of required is submitted:</p>
<div class="codeblock"><code>
$(document).ready(function() {<br /> $('form.required').submit(function() {<br />  &amp;hellip;<br /> });<br />}); 

</code></div>

<p>If there are any error messages still displaying from before, we want to hide them. Also, let’s disable the submit button so just in case, the form cannot be submitted twice. I am also creating a variable that I will be using later to determine if there is an error or not:</p>
<div class="codeblock"><code>
$(document).ready(function() {<br /> $('form.required').submit(function() {<br />  &lt;strong&gt;$('form.required span.error').remove();<br />  $('form.required li.buttons button').attr('disabled','disabled');<br />  var hasError = false;&lt;/strong&gt;<br /> });<br />}); 

</code></div>

<p>Now, we want to check each form field that has a parent list item with a class of <strong>required</strong>:</p>
<div class="codeblock"><code>
$(document).ready(function() {<br /> $('form.required').submit(function() {<br />  $('form.required span.error').remove();<br />  $('form.required li.buttons button').attr('disabled','disabled');<br />  var hasError = false;<br /><br />  &lt;strong&gt;jQuery.each($('form.required ol.forms li.required'),function() {<br />   &amp;hellip;<br />  });&lt;/strong&gt;<br /> });<br />}); 

</code></div>

<p>There are a lot of other jQuery plugins that validate forms, but most of the time, it will just alert the user that the field is required. Instead of doing that, I am going to grab the text from the label element and display that in the error message:</p>

<div class="codeblock"><code>
$(document).ready(function() {<br /> $('form.required').submit(function() {<br />  $('form.required span.error').remove();<br />  $('form.required li.buttons button').attr('disabled','disabled');<br />  var hasError = false;<br /><br />  jQuery.each($('form.required ol.forms li.required'),function() {<br />   &lt;strong&gt;var labelText = $(this).children('label').text();<br />   labelText = labelText.replace(' *','');&lt;/strong&gt;<br />  });<br /> });<br />}); 

</code></div>

<p>Now, we have two different structures of form fields for each list item: a single form field and a grouping of checkboxes or radio buttons. We have to do things a little bit different for each one:</p>

<div class="codeblock"><code>
$(document).ready(function() {<br /> $('form.required').submit(function() {<br />  $('form.required span.error').remove();<br />  $('form.required li.buttons button').attr('disabled','disabled');<br />  var hasError = false;<br /><br />  jQuery.each($('form.required ol.forms li.required'),function() {<br />   var labelText = $(this).children('label').text();<br />   labelText = labelText.replace(' *','');<br /><br />   &lt;strong&gt;if($(this).hasClass('grouping')) {<br />    &amp;hellip; <br />   } else {<br />    &amp;hellip;<br />   }&lt;/strong&gt;<br />  });<br /> });<br />}); 

</code></div>

<p>First, let’s focus on the case when there is a grouping. We want to loop through each input and see if it is checked. If it is, we just increment a counter. Then, if the counter equals zero, meaning we have no fields checked, we display an error message:</p>

<div class="codeblock"><code>
$(document).ready(function() {<br /> $('form.required').submit(function() {<br />  $('form.required span.error').remove();<br />  $('form.required li.buttons button').attr('disabled','disabled');<br />  var hasError = false;<br /><br />  jQuery.each($('form.required ol.forms li.required'),function() {<br />   var labelText = $(this).children('label').text();<br />   labelText = labelText.replace(' *','');<br /><br />   if($(this).hasClass('grouping')) {<br />    &lt;strong&gt;var numSelected = 0;<br />    jQuery.each($(this).find('input'),function() {<br />     if($(this).attr('checked') == true) {<br />      numSelected++;<br />     }<br />    });<br />    <br />    if(numSelected == 0) {<br />     $(this).append('&lt;span class="error"&gt;You must select from '+labelText+'.&lt;/span&gt;');<br />     hasError = true;<br />    }&lt;/strong&gt;<br />   } else {<br />    &amp;hellip;<br />   }<br />  });<br /> });<br />}); 

</code></div>

<p>That seems easy enough, and it’s even easier for the single input fields. We just check to see if the value is empty, and if it is, display the error message:</p>

<div class="codeblock"><code>
$(document).ready(function() {<br /> $('form.required').submit(function() {<br />  $('form.required span.error').remove();<br />  $('form.required li.buttons button').attr('disabled','disabled');<br />  var hasError = false;<br /><br />  jQuery.each($('form.required ol.forms li.required'),function() {<br />   var labelText = $(this).children('label').text();<br />   labelText = labelText.replace(' *','');<br /><br />   if($(this).hasClass('grouping')) {<br />    var numSelected = 0;<br />    jQuery.each($(this).find('input'),function() {<br />     if($(this).attr('checked') == true) {<br />      numSelected++;<br />     }<br />    });<br />    <br />    if(numSelected == 0) {<br />     $(this).append('&lt;span class="error"&gt;You must select from '+labelText+'.&lt;/span&gt;');<br />     hasError = true;<br />    }<br />   } else {<br />    &lt;strong&gt;if(jQuery.trim($(this).children('input, textarea').val()) == '') {<br />     $(this).append('&lt;span class="error"&gt;Please enter your '+labelText+'.&lt;/span&gt;');<br />     hasError = true;<br />    }&lt;/strong&gt;<br />   }<br />  });<br /> });<br />}); 

</code></div>

<p>To finish up, we just check to see if the <code><strong>hasError</strong></code> variable is true. Since this is just a demo form, I just add an alert if the form would submit successfully:</p>
<div class="codeblock"><code>
$(document).ready(function() {<br /> $('form.required').submit(function() {<br />  $('form.required span.error').remove();<br />  $('form.required li.buttons button').attr('disabled','disabled');<br />  var hasError = false;<br /><br />  jQuery.each($('form.required ol.forms li.required'),function() {<br />   var labelText = $(this).children('label').text();<br />   labelText = labelText.replace(' *','');<br /><br />   if($(this).hasClass('grouping')) {<br />    var numSelected = 0;<br />    jQuery.each($(this).find('input'),function() {<br />     if($(this).attr('checked') == true) {<br />      numSelected++;<br />     }<br />    });<br />    <br />    if(numSelected == 0) {<br />     $(this).append('&lt;span class="error"&gt;You must select from '+labelText+'.&lt;/span&gt;');<br />     hasError = true;<br />    }<br />   } else {<br />    if(jQuery.trim($(this).children('input, textarea').val()) == '') {<br />     $(this).append('&lt;span class="error"&gt;Please enter your '+labelText+'.&lt;/span&gt;');<br />     hasError = true;<br />    }<br />   }<br />  });<br /><br />  &lt;strong&gt;if(hasError) {<br />   $('form.required li.buttons button').removeAttr('disabled');<br />   return false;<br />  } else {<br />   alert('The form would submit now');<br />   $('form.required li.buttons button').removeAttr('disabled'); //Remove this line if using for real<br />   return false; //Change this to true when using it for real<br />  }&lt;/strong&gt;<br /> });<br />}); 

</code></div>

<p>Go ahead and take a look at the <a href="//assets.trevor-davis.com/play/forms-revisited/forms-styled-labels-left-customized-more/">demo form</a> to see it in action.</p>

<h2>Conclusion</h2>
<p>With a well structured form, you can easily customize it to your liking with just a little bit of CSS. Then, by using some custom jQuery code, you can easily customize how you would like to have the form validation appear.</p>
<p>With a little more work, you could easily add in validation for things like form elements expecting an email address, zip codes, phone numbers, etc. I will have to save that for another post since this one is quite long.</p>

<p>What do you all think? How do you structure your forms? Which layout of forms do you prefer and why?</p>