Jump to content

Guides

Forms

Description

The form module provides classes for styling forms throughout the suite, with a range of options available to change the appearance and flow.

 

Usage

A form should have the base class ipsForm. In many cases this will be directly on the <form> element, but it can actually appear on any element that contains form elements. The recommended basic DOM structure for a form is as follows:

<form class='ipsForm'>
	<ul>
		<li class='ipsFieldRow'>
			...
		</li>
		<li class='ipsFieldRow'>
			...
		</li>
	</ul>
</form>

In this structure, each field row within the form appears as a <li> element with the class ipsFieldRow

 

Form layouts

There are two layout options for forms: vertical or horizontal. In a vertical form, field labels are displayed above the field element. In horizontal forms, the label appears to the left of the field element. The layout can be controlled by adding the classes ipsForm_vertical or ipsForm_horizontal to the root form element, respectively.

Example of both types:

Note: On small devices and with the responsive CSS enabled, horizontal layout forms will automatically collapse to become vertical layout so that they are easily readable.

 

Field Rows

Each field row within the form has a number of options available, depending on the type of field. The basic structure for a field row is as follows:

<li class='ipsFieldRow'>
	<label for='example' class='ipsFieldRow_label'>
		Example field
	</label>
	<div class='ipsFieldRow_content'>
		<input type='text' id='example' value=''>
	</div>
</li>

The row receives the base class ipsFieldRow. Within this element are the label and content elements. The label receives the class ipsFieldRow_label, while the content wrapper receives the class ipsFieldRow_content. The content element can theoretically contain anything, though naturally it should be kept simple for best usability.

There are several additional classes that can be applied to field rows.

  • ipsFieldRow_primary
    A primary field row causes text inputs to be enlarged to convey importance
  • ipsFieldRow_fullWidth
    Causes appropriate form controls (primarily text-based/select inputs) to take up all available horizontal space
  • ipsFieldRow_noLabel
    If no label is needed, this class can be used to ensure spacing still works as expected. Do give thought to usability before deciding to remove a label.

 

Required fields

To add a 'required' indicator to a field, an element with the class ipsFieldRow_required can be added inside the label element, like so:

<label for='elExample' class='ipsFieldRow_label'>
	Field title <span class='ipsFieldRow_required'>Required</span>
</label>

On horizontal-layout forms, the text inside the 'required' indicator element is automatically replaced with an asterisk in order to conserve space.

 

Field descriptions

Field descriptions can be added immediately following the form control, inside of the field content element, by using the class ipsFieldRow_desc. For example:

<div class='ipsFieldRow_content'>
	<input type='text' size='30'><br>
	<span class='ipsFieldRow_desc'>This is a field description</span>
</div>

 

Checkboxes/Radios

The markup and classes used for checkboxes or radio buttons are by necessity a little different to that described above, because typically the element will sit to the left of the label and appear inline with it.

This is an example of the markup used for checkboxes or radios (note that although the class refers to 'checkbox', it can be used for both types of control):

<li class='ipsFieldRow ipsFieldRow_checkbox'>
	<span class='ipsCustomInput'>
		<input type='checkbox' id='elExampleCheckbox'> 
		<span></span>
	</span>
	<div class='ipsFieldRow_content'>
		<label for='elExampleCheckbox'>Remember me</label>
	</div>
</li>

There are a few differences here. Firstly, the class ipsFieldRow_checkbox has been added to the field row to denote that this row should be handled differently. Secondly, the checkbox control now sits as a direct descendant of the row element, while the label moves inside the content element. Finally, the checkbox itself is wrapped in an element with the classname ipsCustomInput, which allows us to style checkboxes and radios using CSS.

  •  

 

Horizontally-grouped checkboxes

Another common way to display checkbox/radio controls is as a horizontal list of choices. This can be done with the following markup:

<li class='ipsFieldRow'>
	<span class='ipsFieldRow_label'>Choose an option</span>
	<ul class='ipsFieldRow_content ipsList_reset'>
		<li class='ipsFieldRow_inlineCheckbox'>
			<span class='ipsCustomInput'>
				<input type='radio' id='checkbox1'>
				<span></span>
			</span>
			<label for='checkbox1'>Option 1</label>
		</li>
		<li class='ipsFieldRow_inlineCheckbox'>
			<span class='ipsCustomInput'>
				<input type='radio' id='checkbox2'>
				<span></span>
			</span>
			<label for='checkbox2'>Option 2</label>
		</li>
		<li class='ipsFieldRow_inlineCheckbox'>
			<span class='ipsCustomInput'>
				<input type='radio' id='checkbox3'>
				<span></span>
			</span>
			<label for='checkbox3'>Option 3</label>
		</li>
	</ul>
</li>

Here we're building the field row content element as a list (we use ipsList_reset to remove margins and padding), with each list item receiving the class ipsFieldRow_inlineCheckbox to align them horizontally.

The above example produces the following result:

  • Choose an option
    •  
    •  
    •  

 

Vertically-grouped checkboxes

You can also group checkboxes and radio controls in a vertical list. The markup looks like this:

<li class='ipsFieldRow'>
	<span class='ipsFieldRow_label'>Choose an option</span>
	<ul class='ipsFieldRow_content ipsField_fieldList'>
		<li>
			<span class='ipsCustomInput'>
				<input type='checkbox' id='option1'>
				<span></span>
			</span>
			<div class='ipsField_fieldList_content'>
				<label for='option1'>Option 1</label><br>
				<span class='ipsFieldRow_desc'>Option 1 description</span>
			</div>
		</li>
		<li>
			<span class='ipsCustomInput'>
				<input type='checkbox' id='option2'>
				<span></span>
			</span>
			<div class='ipsField_fieldList_content'>
				<label for='option1'>Option 2</label><br>
				<span class='ipsFieldRow_desc'>Option 2 description</span>
			</div>
		</li>
	</ul>
</li>

Which renders as:

  • Choose an option
    •  

      Option 1 description
    •  

      Option 2 description

 

Field loading state

Text-based form inputs (text inputs, date fields, textareas, etc.) can be shown in a loading state by adding the class ipsField_loading (usually with Javascript). This causes the field to show a loading throbber in the field.

Note: this effect is achieved using background images. If you define styles for form fields that specify a background image, the loading effect may not render correctly.

 

Grouping field rows

Adding section headers

You can add a section header to a form by adding a header element of your choice with the class ipsFieldRow_section, like this:

<li>
	<h2 class='ipsFieldRow_section'>A section header</h2>
</li>

 

Fieldsets

Fields can be grouped together in related sets by using fieldsets with the class ipsForm_group. The markup for this kind of structure looks like this:

<div class='ipsForm ipsForm_horizontal'>
	<fieldset class='ipsForm_group'>
		<legend class='ipsForm_groupTitle'>First group</legend>
		<ul class='ipsForm_groupContent'>
			<li class='ipsFieldRow'>
				<!-- Field row content -->
			</li>
			<li class='ipsFieldRow'>
				<!-- Field row content -->
			</li>
		</ul>
	</fieldset>

	<fieldset class='ipsForm_group'>
		<legend class='ipsForm_groupTitle'>Second group</legend>
		<ul class='ipsForm_groupContent'>
			<li class='ipsFieldRow'>
				<!-- Field row content -->
			</li>
			<li class='ipsFieldRow'>
				<!-- Field row content -->
			</li>
		</ul>
	</fieldset>
</div>

This produces (with field row content added):

First group
Second group

The class ipsForm_group is added to a container element - this will typically be a fieldset. Within that element will be a title element, with the class ipsForm_groupTitle. This too can be any element, but a legend element will usually make most sense. Finally, there's an element with the class ipsForm_groupContent which wraps all of the field rows in the group.

 

Complete form example

Here is a complete example of a form, which can be toggled between vertical and horizontal layouts for demonstration purposes. The markup for this example follows after.


  • We keep this confidential
  • Please send me
    •  
    •  
  •  

 

<ul class='ipsForm ipsForm_horizontal' id='form_example'>
	<li class='ipsFieldRow ipsFieldRow_primary ipsFieldRow_fullWidth'>
		<label class='ipsFieldRow_label'>Name <span class='ipsFieldRow_required'>Required</span></label>
		<div class='ipsFieldRow_content'>
			<input type='text' size='30' placeholder='First name'>
		</div>
	</li>
	<li class='ipsFieldRow'>
		<label class='ipsFieldRow_label'>E-mail Address <span class='ipsFieldRow_required'>Required</span></label>
		<div class='ipsFieldRow_content'>
			<input type='text' size='30' placeholder='example@me.com'><br>
			<span class='ipsFieldRow_desc'>We keep this confidential</span>
		</div>
	</li>
	<li class='ipsFieldRow'>
		<span class='ipsFieldRow_label'>Please send me</span>
		<ul class='ipsFieldRow_content ipsList_reset'>
			<li class='ipsFieldRow_inlineCheckbox'>
				<span class='ipsCustomInput'>
					<input type='checkbox'>
					<span></span>
				</span>
				<label>Updates</label>
			</li>
			<li class='ipsFieldRow_inlineCheckbox'>
				<span class='ipsCustomInput'>
					<input type='checkbox'>
					<span></span>
				</span>
				<label>Offers</label>
			</li>
		</ul>
	</li>
	<li class='ipsFieldRow ipsFieldRow_checkbox'>
		<span class='ipsCustomInput'>
			<input type='checkbox'>
			<span></span>
		</span>
		<div class='ipsFieldRow_content'>
			<label class='ipsFieldRow_label'><strong>I agree to the terms and conditions</strong></label>
		</div>
	</li>
	<li class='ipsFieldRow'>
		<div class='ipsFieldRow_content'>
			<button type='submit' class='ipsButton ipsButton_medium ipsButton_primary'>Submit</button>
		</div>
	</li>
</ul>

 


  Report Guide


×