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 .
Single form input
For left-aligned labels or standard labels (above the field), we use the same exact markup.
<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.
<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.
<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 by Zander Martineau () on .
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.
<!-- 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="[email protected]" 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.
<!-- 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="[email protected]" 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
<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
<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
<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
<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 for more details.
<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'));