Form styling

Forms and their fields are often a nightmare to style, that is why Kickoff includes a great boilerplate for styling them. All styles can be found in _forms.scss.

Single form input

For left-aligned labels or standard labels (above the field), we use the same exact markup.

_forms.scss
<div class="form-controlGroup">
	<label class="form-label" for="sf-text">Label</label>
	<div class="form-controlGroup-inputWrapper">
		<input class="form-input" type="text" id="sf-text" placeholder="Some text" required/>
	</div>
</div>

Forms with labels above inputs

Having forms styled like this depends on specific markup with specific class names. Please use the example code below as a guide.

_forms.scss
Your form
<form class="form">
	<fieldset class="form-fieldset">
		<legend class="form-legend">Your form</legend>
		<div class="form-controlGroup">
			<label class="form-label" for="text">Text</label>
			<div class="form-controlGroup-inputWrapper">
				<input class="form-input" type="text" id="text" placeholder="Some text" required/>
			</div>
		</div>

		<div class="form-controlGroup">
			<label class="form-label" for="comments">Textarea</label>
			<div class="form-controlGroup-inputWrapper">
				<textarea class="form-input form-input--textarea" id="comments" rows="3" cols="50"></textarea>
			</div>
		</div>
	</fieldset>

	<div class="form-actions text_centre">
		<input type="submit" value="Submit" class="btn btn--primary" />
		<input type="reset" class="btn" value="Cancel" />
	</div>
</form>

Forms with inline labels

Assuming you use the same markup as above, simply add a .form--horizontal class to the <form> element and you’ll now have right aligned, inline form labels in an instant.

_forms.scss
Your form
<form class="form form--horizontal">
	<fieldset class="form-fieldset">
		<legend class="form-legend">Your form</legend>
		<div class="form-controlGroup">
			<label class="form-label" for="text">Text</label>
			<div class="form-controlGroup-inputWrapper">
				<input class="form-input" type="text" id="text" placeholder="Some text" required/>
			</div>
		</div>

		<div class="form-controlGroup">
			<label class="form-label" for="comments">Textarea</label>
			<div class="form-controlGroup-inputWrapper">
				<textarea class="form-input form-input--textarea" id="comments" rows="3" cols="50"></textarea>
			</div>
		</div>
	</fieldset>

	<div class="form-actions text_centre">
		<input type="submit" value="Submit" class="btn btn--primary" />
		<input type="reset" class="btn" value="Cancel" />
	</div>
</form>

Form themes

Version 8 of Kickoff introduced basic theming support for forms. What you have seen up until this point is the ‘standard’ theme that we have had for quite some time. What you see below is the experimental ‘Material design’ theme.

See the Pen Kickoff Material design for theme by Zander Martineau (@mrmartineau) on CodePen.

How to switch themes

Switching themes is fairly trivial. Find the scss/components/forms/forms.scss file and change the @import value to the one specified in the comments below:

/**
 * Form themes
 * This file contains the base form styles and each theme file contains
 * overrides and additions.
 *
 * Choose from:
 * - `standard`: the original Kickoff form theme
 * - `material`: basic version of Google's Material design forms
 *
 * Usage: (choose from)
 * @import "form-theme-standard";
 * @import "form-theme-material";
 */
@import "form-theme-standard";

Creating your own theme

If you need to create your own theme, we recommend amending one of the existing themes (‘standard’ or ‘material’).

Material theme markup

The markup for the material design theme is slightly different, please see the source of the Codepen demo above, or the snippet beneath that for an example.

<div class="form-controlGroup">
	<input class="form-input" type="text" name="" id="firstname" required/>
	<label class="form-label" for="firstname">First name</label>
	<i class="form-inputBar"></i>
</div>

Multi column forms with labels above inputs

Multi-column forms are easy to achieve by using the existing Kickoff grid. See the comments in the code below for implementation details.

_forms.scss
<!-- Apply the grid  class: .g -->
<div class="g g--stack g--gutter">
	<!-- Add .g-col and .g-span# to the .form-controlGroup -->
	<div class="form-controlGroup g-col g-span6--mid">
		<label class="form-label" for="fm-text">Text</label>
		<div class="form-controlGroup-inputWrapper">
			<input class="form-input" type="text" id="fm-text" placeholder="Some text" required/>
		</div>
	</div>
	<div class="form-controlGroup g-col g-span6--mid">
		<label for="fm-email" class="form-label">Email</label>
		<div class="form-controlGroup-inputWrapper">
			<input class="form-input" type="email" id="fm-email" placeholder="tech@tmw.co.uk" required/>
		</div>
	</div>
</div>

Form field states

You can easily update field states by adding modifier classes to .form-controlGroup. See the comments in the code below for implementation details.

_forms.scss
<!-- Add .has-success modifier class for valid or successful fields -->
<div class="form-controlGroup has-success">
	<label class="form-label" for="st-success">Success</label>
	<div class="form-controlGroup-inputWrapper">
		<input class="form-input" type="text" id="st-success" placeholder="Some text" value="A value" required/>
	</div>
</div>

<!-- Add .has-error modifier class for invalid or unsuccessful fields -->
<div class="form-controlGroup has-error">
	<label for="st-email" class="form-label">Error</label>
	<div class="form-controlGroup-inputWrapper">
		<input class="form-input" type="email" id="st-email" placeholder="tech@tmw.co.uk" value="A value" required/>
	</div>
</div>

<!-- Add .has-warning modifier class to give warning -->
<div class="form-controlGroup has-warning">
	<label for="st-password" class="form-label">Warning</label>
	<div class="form-controlGroup-inputWrapper">
		<input class="form-input" type="password" id="st-password" placeholder="Your password" value="A value" />
	</div>
</div>

Custom field elements

Improved styling for checkboxes, radios & file upload.

Custom checkbox inputs

_forms-custom-radioscheckboxes.scss
<label class="control control--custom" for="checkbox1">
	<input class="control--custom-input" type="checkbox" id="checkbox1" name="mycheckboxBtn" value="A value" checked/>
	<span class="control-indicator control-indicator--checkbox"></span>
	My checkbox Button Label Text
</label>

<label class="control control--custom" for="checkbox2">
	<input class="control--custom-input" type="checkbox" id="checkbox2" name="mycheckboxBtn" value="A value" checked/>
	<span class="control-indicator control-indicator--tickbox"></span>
	My tickbox Label Text
</label>

Custom radio inputs

_forms-custom-radioscheckboxes.scss
<label class="control control--custom">
	<input class="control--custom-input" type="radio" id="radio1" name="myRadioBtn" checked/>
	<span class="control-indicator control-indicator--radio"></span>
	My Radio Button Label Text
</label>

<label class="control control--custom">
	<input class="control--custom-input" type="radio" id="radio2" name="myRadioBtn" />
	<span class="control-indicator control-indicator--radio"></span>
	Another Radio Button Label Text
</label>

Custom select element

_forms-custom-select.scss
<div class="form-controlGroup">
	<label for="cs-choice" class="form-label">Custom select</label>
	<div class="form-controlGroup-inputWrapper form-controlGroup-inputWrapper--select">
		<select id="cs-choice" name="cs-choice" class="form-input form-input--select">
			<option value="--">Select title</option>
			<option value="Mr">Mr</option>
			<option value="Mrs">Mrs</option>
		</select>
	</div>
</div>

Custom file upload fields

_forms-custom-file.scss
<div class="form-controlGroup">
		<label class="form-label" for="file">File upload</label>

		<div class="form-controlGroup-inputWrapper">
				<label class="form-input form-input--file">
						<span class="form-input--file-text">Choose file..</span>
						<span class="form-input--file-button">Browse</span>
						<input class="form-input-file" type="file" id="file" accept="image/*" size="14" />
				</label>
		</div>
</div>
var fileInput = document.querySelector('.form-input-file');
var fileInputText = document.querySelector('.form-input--file-text');
fileInputTextContent = fileInputText.textContent;

fileInput.addEventListener('change', function(e) {
	var value = e.target.value.length > 0 ? e.target.value.replace("C:\\fakepath\\", "") : fileInputTextContent;
	fileInputText.textContent = value;
});

Validation With D'accord

HTML 5 validation for Kickoff. See D'accord for more details.

_forms.scss
<form class="form form-daccord">
	<div class="form-controlGroup">
		<label class="form-label" for="field1">Text, required, maxlength 10</label>
		<input class="form-input" id="field1" name="field1" type="text" required maxlength="10">
	</div>
	<div class="form-controlGroup">
		<label class="form-label" for="field2">Email, required</label>
		<input class="form-input" id="field2" name="field2" type="email" required>
	</div>
	<div class="form-controlGroup">
		<label class="form-label" for="field3">Text, required with message</label>
		<input class="form-input" id="field3" name="field3" type="text" data-val-required="This field is required" required>
		<div class="form-message"></div>
	</div>
	<button class="btn btn--primary" type="submit">Submit</button>
</form>
new Daccord(document.querySelector('.form-daccord'));

Where next?