A short help text for a textarea.
<form action="" method="" class="form">
	<fieldset class="form__group">
		<label for="inputid" class="form__label">Name</label>
		<input id="inputid" name="inputname" type="text" class="form__field" />
	</fieldset>
	<fieldset class="form__group">
		<label for="textareid" class="form__label">Comment <span class="form__label-meta">(optional)</span></label>
		<span class="form__helptext" id="textareahelptext">A short help text for a textarea.</span>
		<textarea name="textareaname" id="textareaid" class="form__textarea" aria-describedby="textareahelptext"></textarea>
	</fieldset>
	<div class="form__actions">
		<button class="button button--default" type="reset">Reset</button>
		<button class="button button--primary" type="submit">Send</button>
	</div>
</form>

About labels and placeholders

Always use a label with your form elements. Don’t use the placeholder attribute as a subsitute for a label. The placeholder attribute isn’t meant to give an extensive description. It’s meant to be a guideline or a hint.

Bad example: placeholder used as label

Good example: separate label and placeholder

<!-- BAD -->
<input type="email" class="form__field" placeholder="e-mail address" />

<!-- GOOD -->
<label class="form__label" for="searchplaceholder">Search</label>
<input type="email" class="form__field" id="searchplaceholder" placeholder="Search query here" />

Form elements

Form elements can be wrapped by .form__group. This comes in handy when you want to implement validation later. This wrapper can be a <div> or a <fieldset>. It also adds spacing. If you don’t need the spacing and validation can be done on other elements, you can omit this.

<div class="form__group">
	<label for="nameid" class="form__label">Name</label>
	<input id="inputid" name="inputname" type="text" class="form__field" />
</div>

<fieldset class="form__group">
	<label for="nameid" class="form__label">Name</label>
	<input id="inputid" name="inputname" type="text" class="form__field" />
</fieldset>

Date input

<label for="dateid" class="form__label">Date</label>
<input type="date" id="dateid" name="datename" class="form__field" />

Search field

<label for="searchid" class="form__label">Search</label>
<input type="search" class="form__field" id="searchid" name="searchname" placeholder="Search query here" />

Telephone number input

<label for="telephoneid" class="form__label">Telephone</label>
<input type="tel" class="form__field" id="telephoneid" name="telephonename" />
Attribute Description
placeholder Forbidden Not allowed for a11y reasons, use .form__help-text if you want to explain the pattern. See help text section

Number input

<label for="numberid" class="form__label">Number</label>
<input type="number" id="numberid" name="numbername" class="form__field" step="3" />

Email input

<label for="emailid" class="form__label">Email</label>
<input type="email" id="emailid" name="emailname" class="form__field" />
Attribute Description
placeholder Forbidden Not allowed for a11y reasons

File upload

<label for="fileid" class="form__label">File</label>
<input type="file" id="fileid" name="filename" class="form__field" accept="image/*" />

Password field

<label for="passwordid" class="form__label">Password</label>
<input type="password" id="passwordid" name="passwordname" class="form__field" value="" />
Attribute Description
placeholder Forbidden Not allowed for a11y reasons

Color picker

<label for="colorid" class="form__label">Colorpicker</label>
<input type="color" id="colorid" name="colorname" class="form__field" />

Checkboxes and radio buttons

By default checkboxes and radio buttons are stacked.

Choose a brand
<legend class="form__label" id="brandpicker">Choose a brand</legend>
<div class="form__checkbox">
	<label class="form__checkbox__label">
		<input type="checkbox" class="form__checkbox__input" value="Levis" aria-describedby="brandpicker" /> Levis
	</label>
</div>
<div class="form__checkbox">
	<label class="form__checkbox__label">
		<input type="checkbox" class="form__checkbox__input" value="Lee" checked="checked" aria-describedby="brandpicker" /> Lee
	</label>
</div>
Are you happy?
<fieldset class="form__group" >
	<legend class="form__label" id="happiness">Are you happy?</legend>
	<div class="form__radio">
		<label class="form__radio__label">
			<input type="radio" name="happiness" class="form__radio__input" value="yes" aria-describedby="happiness" /> Yes
		</label>
	</div>
	<div class="form__radio">
		<label class="form__radio__label">
			<input type="radio" name="happiness" class="form__radio__input" value="no" aria-describedby="happiness" /> No
		</label>
	</div>
</fieldset>
Attribute Description
id On legend, needs to be unique
aria-describedby Value has to be the same as the id on legend

Inline checkboxes and radio buttons

If you add modifier .form__checkbox--inline or .form__radio--inline they will display inline.

Choose a brand
<legend class="form__label" id="brandpicker2">Choose a brand</legend>
<div class="form__checkbox form__checkbox--inline">
	<label class="form__checkbox__label">
		<input type="checkbox" class="form__checkbox__input" value="Levis" aria-describedby="brandpicker2" /> Levis
	</label>
</div>
<div class="form__checkbox form__checkbox--inline">
	<label class="form__checkbox__label">
		<input type="checkbox" class="form__checkbox__input" value="Lee" checked="checked" aria-describedby="brandpicker2" /> Lee
	</label>
</div>
Are you happy?
<fieldset class="form__group">
	<legend class="form__label" id="happiness2">Are you happy?</legend>
	<div class="form__radio form__radio--inline">
		<label class="form__radio__label">
			<input type="radio" name="happiness2" class="form__radio__input" value="yes" aria-describedby="happiness2" /> Yes
		</label>
	</div>
	<div class="form__radio form__radio--inline">
		<label class="form__radio__label">
			<input type="radio" name="happiness2" class="form__radio__input" value="no" aria-describedby="happiness2" /> No
		</label>
	</div>
</fieldset>

Selects

<label for="themepicker" class="form__label">Pick a theme</label>
<select name="themepicker" id="themepicker" class="form__field">
	<optgroup label="code">
		<option value="">Monokai</option>
		<option value="">Manni</option>
	</optgroup>
	<optgroup label="events" disabled="disabled">
		<option value="">Xmas</option>
		<option value="">Easter</option>
	</optgroup>
</select>
<label for="countrypicker" class="form__label">Select your favorite countries</label>
<select name="countrypicker" id="countrypicker" class="form__field" multiple="multiple">
	<option value="">Belgium</option>
	<option value="">Netherlands</option>
	...
</select>

Disabled and readonly states

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab, ipsum.

<input type="text" class="form__field" disabled="disabled" />
<input type="text" class="form__field" readonly="readonly" value="Rebels Squad" />

Help text

Sometimes a field needs extra explanation when a placeholder and a label isn’t enough. You can do this with .form__helptext.

Please add your area code
<label for="telephoneid" class="form__label">Telephone</label>
<span class="form__helptext" id="telephonehelptext">Please add your area code</span>
<input type="tel" class="form__field" id="telephoneid" name="telephonename" aria-describedby="telephonehelptext" />
Must be at least 8 characters long and contain at least 1 digit and 1 uppercase
<label for="passwordid2" class="form__label">Password</label>
<span class="form__helptext">Must be at least 8 characters long and contain at least 1 digit and 1 uppercase</span>
<input type="password" id="passwordid2" name="passwordname2" class="form__field" value="" minlength="8" />

Validation

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Culpa, officia.

<fieldset class="form__group is-valid">
	<label for="requiredvalidinputid" class="form__label">Name</label>
	<input id="requiredvalidinputid" name="requiredvalidinputid" type="text" class="form__field" required="required" />
</fieldset>

<fieldset class="form__group is-invalid">
	<label for="requiredinvalidinputid" class="form__label">Name</label>
	<input id="requiredinvalidinputid" name="requiredinvalidinputid" type="text" class="form__field" required="required" />
	<span class="form__feedback">Please enter your name</span>
</fieldset>
Selector Description
.is-invalid Gives visual feedback with the error state
.js-is-invalid Use the .js- prefix when you toggle these classes with JavaScript
.is-valid Gives visual feedback with the success state
.js-is-valid Use the .js- prefix when you toggle these classes with JavaScript

Layouting

If you need to layout different fields according a grid pattern, you can use our grid layout.

<fieldset class="form__fieldset">
	<div class="grid">
		<div class="col-6">
			<div class="form__group">
				<label for="" class="form__label">First name</label>
				<input type="text" class="form__field" />
			</div>
		</div>
		<div class="col-6">
			<div class="form__group">
				<label for="" class="form__label">Last name</label>
				<input type="text" class="form__field" />
			</div>
		</div>
	</div>
</fieldset>

Special cases

If you want more flexibility, vertical alignment and let the browser handle the layout, replace the grid layout with a flexbox layout.

An example with a date picker and time input.

Pick a date and time
<fieldset class="form__fieldset">
	<legend class="form__label">Pick a date and time</legend>
	<div class="form__flex">
		<div class="form__box">
			<input type="date" class="form__field" aria-label="Choose a date" />
		</div>
		<div class="form__box form__box--joiner">
			<div class="form__joiner-text" role="presentation">at</div>
		</div>
		<div class="form__box">
			<input type="time" class="form__field" aria-label="Enter a time" />
		</div>
	</div>
</fieldset>
Selector Description
.form__flex Creates a flexbox layout
.form__box The flex items. Nest other form components in this element.

Grouped form elements in a panel

Check out the panel module, it has an example with the semantically correct way to group form elements in a fieldset with a legend. The outcome is the same. Just make sure you don’t nest fieldsets.