Field
A layout wrapper that places a control’s label, description and validation feedback.
Bootstrap’s field docs describe the markup and CSS.
Example
bsFormField adds .form-field, a CSS grid that stacks the label, control, help text and feedback. The field generates an id for the control unless you set one, sets for on its bsFormLabel or bsLabel, and points the control’s aria-describedby to its bsFormText.
<div bsFormField>
<label bsFormLabel>Email address</label>
<input type="email" bsFormControl placeholder="[email protected]" />
<div bsFormText>We’ll never share your email with anyone else.</div>
</div>Select
Works the same way with <select> elements.
<div bsFormField>
<label bsFormLabel>Country</label>
<select bsFormControl>
<option selected>Choose one…</option>
<option value="1">United States</option>
<option value="2">Canada</option>
<option value="3">United Kingdom</option>
</select>
</div>Textarea
And with <textarea> elements. Descriptions are optional.
<div bsFormField>
<label bsFormLabel>Message</label>
<textarea bsFormControl rows="3"></textarea>
<div bsFormText>Be sure to include relevant details.</div>
</div>Checkbox
When a checkbox is a direct child, the field switches to two columns: the checkbox, then its label. Use bsLabel, which sets for without adding a class.
<div bsFormField>
<input type="checkbox" bsCheck />
<label bsLabel>Remember me</label>
</div>Radio
Radios use the same two-column layout. Wrap each radio and its label in its own field.
<div class="vstack gap-2">
<div bsFormField>
<input type="radio" bsRadio name="fieldRadioGroup" value="one" />
<label bsLabel>Option one</label>
</div>
<div bsFormField>
<input type="radio" bsRadio name="fieldRadioGroup" value="two" />
<label bsLabel>Option two</label>
</div>
</div>Grouped
Wrap several fields in a .form-group to put related controls under a shared label. Use a <fieldset> with a <legend> so screen readers announce the group name.
<fieldset class="form-group">
<legend class="form-label">Shipping method</legend>
<div bsFormField>
<input type="radio" bsRadio name="fieldGroupRadio" value="standard" />
<label bsLabel>Standard</label>
</div>
<div bsFormField>
<input type="radio" bsRadio name="fieldGroupRadio" value="express" />
<label bsLabel>Express</label>
</div>
<small class="form-text">Choose your preferred shipping speed.</small>
</fieldset>Group cards
Add card to each field for a card that highlights the selected option. Put the label and description in a .form-field-content.
<fieldset class="form-group">
<legend class="form-label">Select a plan</legend>
<div class="vstack gap-1">
<div bsFormField card>
<input type="radio" bsRadio name="fieldPlan" value="basic" checked />
<div class="form-field-content">
<label bsLabel>Basic</label>
<small bsFormText>$9/month — For individuals.</small>
</div>
</div>
<div bsFormField card>
<input type="radio" bsRadio name="fieldPlan" value="pro" />
<div class="form-field-content">
<label bsLabel>Pro</label>
<small bsFormText>$29/month — For teams.</small>
</div>
</div>
</div>
</fieldset>Switch
Switches also use the two-column layout.
<div bsFormField>
<div bsSwitch>
<input type="checkbox" bsSwitch />
</div>
<label bsLabel>Enable notifications</label>
</div>Overhead label
Add a bsFormLabel to put a title above a checkbox, radio or switch. It spans both columns.
<div bsFormField>
<label bsFormLabel>Terms and conditions</label>
<input type="checkbox" bsCheck />
<div class="form-field-content">
<label bsLabel>I agree to the terms</label>
<small bsFormText>Please read before agreeing.</small>
</div>
</div>Descriptions
Add a bsFormText after the label. For checkboxes and radios, wrap the label and description in a .form-field-content.
<div class="vstack gap-3">
<div bsFormField>
<input type="checkbox" bsCheck />
<div class="form-field-content">
<label bsLabel>Subscribe to updates</label>
<small bsFormText>We’ll send you a weekly digest of what’s new.</small>
</div>
</div>
<div bsFormField>
<input type="radio" bsRadio name="fieldRadioDesc" />
<div class="form-field-content">
<label bsLabel>Standard shipping</label>
<small bsFormText>Arrives in 5-7 business days.</small>
</div>
</div>
<div bsFormField>
<label bsFormLabel>Username</label>
<input bsFormControl />
<small bsFormText>Must be 3-20 characters, letters and numbers only.</small>
</div>
</div>Validation
bsInvalidFeedback and bsValidFeedback stack correctly in a field for every control type. While the control shows a state, the matching feedback joins its aria-describedby. See Validation for how states are set.
<form class="vstack gap-3" bsValidate="valid" [formGroup]="form">
<div bsFormField>
<label bsFormLabel>Email address</label>
<input type="email" bsFormControl formControlName="email" autocomplete="email" />
<div bsInvalidFeedback>Please enter a valid email address.</div>
<div bsValidFeedback>Looks good!</div>
</div>
<div bsFormField>
<input type="checkbox" bsCheck formControlName="terms" />
<div class="form-field-content">
<label bsLabel>Agree to terms and conditions</label>
<div bsInvalidFeedback>You must agree before submitting.</div>
</div>
</div>
<button type="submit" bsButton theme="primary" class="align-self-start">Submit</button>
</form>API
BsFormField
Selector: [bsFormField] · Exported as: bsFormField
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
card | boolean | false | Card style that highlights the selected checkbox or radio. |
Methods
| Name | Type | Description |
|---|---|---|
controlId | Signal<string | null> | Id of the first control in the field. |
BsFormLabel
Selector: label[bsFormLabel]
BsLabel
Selector: label[bsLabel]
BsFormText
Selector: [bsFormText]
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
id | string | generated | Element id. Generated when not set. |