Skip to main content
Version: 1.0.x

Form components

Forms provide the most common control styles used in forms, including input, textarea, select, checkbox, radio and switch.

Group & Inline

The two components and can be used tomanage the flow of elements like label, inputs and validation texts.
In some case, the class can be replace by the utility class to add some margin.

This field is required
Are you a front-end developer?
<div class="c-form__group">
<label class="c-form__label" for="test">Test</label>
<input class="c-form__control" type="text" id="test" name="test" required />
<span class="c-form__text">This field is required</span>
</div>

<fieldset class="c-form__group">
<div class="c-form__inline">
<legend>Are you a front-end developer?</legend>
<div class="c-form__toggle">
<input class="c-form__toggle-input" type="radio" name="tg" id="tg1" />
<label class="c-form__toggle-label" for="tg1">Yes</label>
<input class="c-form__toggle-input" type="radio" name="tg" id="tg2" />
<label class="c-form__toggle-label" for="tg2">No</label>
</div>
</div>
</fieldset>

Label

The .c-form__label class add some aesthetic styles like font-weight and adjust the vertical rhythm.

<label class="c-form__label" for="my-label">My label</label>

Controls (a.k.a. Input and Textarea)

The .c-form__control component can be use both on input (text, email, password...) and textarea.

<div class="c-form__group">
<label class="c-form__label" for="name">Name</label>
<input class="c-form__control" type="text" id="name" name="name" placeholder="Name">
</div>

Select

<div class="c-form__group">
<select name="list" id="list" class="c-form__select">
<option value disabled selected>Choose an option</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
...
</select>
</div>

Choice fields

Checkbox

<div class="c-form__group">
<div class="c-form__check">
<input class="c-form__check-input" type="checkbox" name="checkfield" id="check1" required>
<label class="c-form__check-label" for="check1">Option 1</label>
</div>
<div class="c-form__check">
<input class="c-form__check-input" type="checkbox" name="checkfield" id="check2">
<label class="c-form__check-label" for="check2">Option 2</label>
</div>
</div>

Radio

Gender
<fieldset class="c-form__group">
<legend class="c-form__label">Gender</legend>
<div class="c-form__check">
<input class="c-form__check-input" type="radio" name="gender" id="male" required>
<label class="c-form__check-label" for="male">Male</label>
</div>
<div class="c-form__check">
<input class="c-form__check-input" type="radio" name="gender" id="female">
<label class="c-form__check-label" for="female">Female</label>
</div>
</fieldset>

Switch (available soon)

This will be an alternative style for checkbox inputs.

Toggle

The toggle component allow a specific display for radio inputs when the possible choice are like "true/false" answers.

Are you sure?
<fieldset class="c-form__group">
<div class="c-form__inline">
<legend>Are you sure?</legend>
<div class="c-form__toggle">
<input class="c-form__toggle-input" type="radio" name="toggle" id="toggle1">
<label class="c-form__toggle-label" for="toggle1">Yes</label>
<input class="c-form__toggle-input" type="radio" name="toggle" id="toggl2">
<label class="c-form__toggle-label" for="toggl2">No</label>
</div>
</div>
</fieldset>

File

Add a profile picture
<div class="c-form__group"><span class="c-form__label">Add a profile picture</span>
<input class="c-form__file-input" type="file" name="picture" id="picture" data-multiple-caption="{count} files selected" multipl required>
<label class="c-form__file-label" for="picture">
<strong>Choose a file</strong>
<span></span>
</label>
</div>

Next, you can add this simple JavaScript script to automatically update the input field with the name of the file(s) selected.

<script>
const getNextSibling = (el, selector) => {
let sibling = el.nextElementSibling

// If there's no selector, return the first sibling
if (!selector) return sibling

// If the sibling matches our selector, use it
// If not, jump to the next sibling and continue the loop
while (sibling) {
if (sibling.matches(selector)) return sibling

sibling = sibling.nextElementSibling
}

return sibling
}

if (document.querySelector('input[type=file]')) {
Array.prototype.forEach.call(
document.querySelectorAll('input[type=file]'),
(input) => {
const label = getNextSibling(input, 'label')

input.addEventListener('change', (e) => {
label.querySelector('span').innerHTML = 'Loading...'

if (e.target) {
let text = ''
const { files } = input
const multipleText =
input.getAttribute('data-multiple-caption') ||
'{count} files selected'

if (files && files.length > 1) {
text = multipleText.replace('{count}', files.length.toString())
} else {
text = e.target.value.split('\\').pop()
}

if (text) {
label.querySelector('span').innerHTML = text
}
}
})
},
)
}
</script>

Helpers

You can add some indications by adding texts below fields.
Help texts should be associated with the form control it relates to using the aria-describedby attribute.

This field is required
<div class="c-form__group">
<label class="c-form__label" for="username">Username</label>
<input class="c-form__control" type="text" id="username" name="username" aria-describedby="usernameHelpText" required>
<span class="c-form__text" id="usernameHelpText">This field is required</span>
</div>

An other possibility is to use the helper component to display more content inside a tooltip.

The helper will be automatically shown if the form element is focused (works with controls, select and file elements).

You can only use alphanumeric character. You will be able to modiy it later, so don't worry it you don't like anymore your username.
Make the good choice!
Add a profile picture
Get better results by adding a profile picture
<div class="c-form__group">
<label class="c-form__label" for="username">Username</label>
<input class="c-form__control" type="text" id="username" name="username">
<span class="c-form__helper">
<div class="c-form__helper-content">
<span>You can only use alphanumeric character. You will be able to modiy it later, so don't worry it you don't like anymore your username.</span>
</div>
</span>
</div>

Disabled styles

Gender
Active or not the checkbox
Add a profile picture
<div class="c-form__group">
<label class="c-form__label" for="name">Name</label>
<input class="c-form__control" type="text" id="name" name="name" placeholder="Name" disabled>
</div>
<div class="c-form__group">
<label class="c-form__label" for="message">Message</label>
<textarea class="c-form__control" id="message" name="message" placeholder="Add your message" disabled></textarea>
</div>
<div class="c-form__group">
<label class="c-form__label">Choose an option</label>
<select class="c-form__select" name="list" id="list" disabled>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
</div>
<fieldset class="c-form__group" disabled>
<legend class="c-form__label">Gender</legend>
<div class="c-form__check">
<input class="c-form__check-input" type="radio" name="gender" id="male">
<label class="c-form__check-label" for="male">Male</label>
</div>
<div class="c-form__check">
<input class="c-form__check-input" type="radio" name="gender" id="female">
<label class="c-form__check-label" for="female">Female</label>
</div>
</fieldset>
<div class="c-form__group">
<span class="c-form__label">Active or not the checkbox</span>
<div class="c-form__check">
<input class="c-form__check-input" type="checkbox" name="checkfield" id="check" disabled>
<label class="c-form__check-label" for="check">Option 1</label>
</div>
</div>

Validation styles / feedbacks

The validation messages work a bit like the helper texts.
This behavior is greatly inspired by Bootstrap.

Radio (valid)
Radio (invalid)
Checkbox (valid)
Checkbox (invalid)
File (valid)
File (invalid)

The states can be managed by using the .is-valid or .is-invalid classes to the form element.

Other, it's possible to detect the submission of the form and valid it with JavaScript. Then, you need to add the .is-validated class to the form to display feedback messages.

<script>
const forms = document.querySelectorAll('.needs-validation')

// Loop over them and prevent submission
Array.prototype.slice.call(forms)
.forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}

form.classList.add('is-validated')
}, false)
})
</script>