Form group
Wraps a form control with its label, hint text and error message.
On this page
Preview
import { FormGroup, Hint, Input, Label } from '@govtech-bb/react';
<FormGroup>
<Label htmlFor="nis-number">NIS number</Label>
<Hint id="nis-number-description">
Your National Insurance number, for example 123456
</Hint>
<Input
id="nis-number"
name="nis-number"
aria-describedby="nis-number-description"
/>
</FormGroup>;<div class="govbb-form-group">
<label class="govbb-label" for="nis-number">NIS number</label>
<span class="govbb-hint" id="nis-number-description">
Your National Insurance number, for example 123456
</span>
<input
class="govbb-input"
id="nis-number"
name="nis-number"
type="text"
aria-describedby="nis-number-description"
/>
</div>The Form group is the shared scaffolding around every form control: a wrapper
(.govbb-form-group) that stacks the label (.govbb-label), optional hint
text (.govbb-hint), optional error message (.govbb-error-message) and the
control itself with consistent spacing. It holds no state: compose the pieces
you need.
For rules shared by every kind of control, including labels, hint text, width, states and validation, see the Form fields foundation.
Usage
When to use
- Use a form group to keep one control with its label, hint and error message.
- Use a fieldset and legend when several controls answer one question.
When not to use
- Do not use a form group as a general page layout wrapper.
- Do not put essential instructions in placeholder text or inside a label.
Best practices
Keep supporting text in a predictable order
Show the label first, then either hint text or an error message, followed by the
control. When invalid, the error replaces the hint and aria-describedby
points at the error.
Ask only what the service needs
Prefer one clear question per page for complex services. Mark optional fields explicitly rather than relying on an unexplained asterisk, and preserve user answers when validation fails.
Error messages
When a field fails validation, add an error message between the label (or
hint) and the control. Give it role="alert" so it is announced, mark the
control with aria-invalid="true", and point aria-describedby at the error
message id. Keep messages specific and actionable, such as “Enter your NIS
number”.
import { ErrorMessage, FormGroup, Input, Label } from '@govtech-bb/react';
<FormGroup>
<Label htmlFor="licence-number">Licence number</Label>
<ErrorMessage id="licence-number-error" role="alert">
Enter your driver's licence number
</ErrorMessage>
<Input
id="licence-number"
name="licence-number"
aria-invalid
aria-describedby="licence-number-error"
/>
</FormGroup>;<div class="govbb-form-group">
<label class="govbb-label" for="licence-number">Licence number</label>
<span class="govbb-error-message" id="licence-number-error" role="alert">
Enter your driver's licence number
</span>
<input
class="govbb-input"
id="licence-number"
name="licence-number"
type="text"
aria-invalid="true"
aria-describedby="licence-number-error"
/>
</div>Grouping related fields with a fieldset
When several controls answer a single question (radios, checkboxes, or the
parts of a date), wrap them in a fieldset (.govbb-fieldset) with a legend
(.govbb-fieldset__legend) inside the form group. The React Fieldset
component supplies the form-group wrapper. The legend acts as the question;
each control keeps its own label.
import { Fieldset, Hint, Radio } from '@govtech-bb/react';
<Fieldset
legend="Where do you want to collect your passport?"
aria-describedby="collection-description"
>
<Hint id="collection-description">Choose the office closest to you</Hint>
<Radio id="collect-bridgetown" name="collection" label="Bridgetown" />
<Radio id="collect-holetown" name="collection" label="Holetown" />
</Fieldset>;<div class="govbb-form-group">
<fieldset class="govbb-fieldset" aria-describedby="collection-description">
<legend class="govbb-fieldset__legend">
Where do you want to collect your passport?
</legend>
<span class="govbb-hint" id="collection-description">
Choose the office closest to you
</span>
<div class="govbb-radio-item">
<input
class="govbb-radio"
id="collect-bridgetown"
type="radio"
name="collection"
/>
<label class="govbb-radio-item__label" for="collect-bridgetown">
Bridgetown
</label>
</div>
<div class="govbb-radio-item">
<input
class="govbb-radio"
id="collect-holetown"
type="radio"
name="collection"
/>
<label class="govbb-radio-item__label" for="collect-holetown">
Holetown
</label>
</div>
</fieldset>
</div>