Components (5): Forms
form
div.form-group
label
Attribute
for="exampleInputEmail1"
Email address
input.form-control
Attributes
id="exampleInputEmail1"
type="email"
placeholder="Enter email"
aria-describedby="emailHelp"
small.form-text.text-muted
Attribute
id="emailHelp"
We'll never share your email with anyone else.
div.form-group
label
Attribute
for="exampleInputPassword1"
Password
input.form-control
Attributes
id="exampleInputPassword1"
type="password"
placeholder="Password"
div.form-check
input.form-check-input
Attributes
id="exampleCheck1"
type="checkbox"
label.form-check-label
Attribute
for="exampleCheck1"
Check me out
button.btn.btn-primary.mt-2
Attribute
type="submit"
Submit
Set .form-control
to input controls ( input
, select
, textarea
) ⇒
displays with a rounded border by 100% width
input
+attribute type="(text|email|password|number|...)"
Browser default input
+attribute type="email"
input.form-control
+attribute type="email"
select
Browser default select
select.form-control
Browser default select
+attribute multiple
select.form-control
+attribute multiple
textarea
Browser default textarea
textarea.form-control
input
+attribute type="file"
Set .form-control-file
to file input controls (input
+attribute type="file"
)
Browser default input
+attribute type="file"
input.form-control-file
+attribute type="file"
(⇒ Note 1)
Add .form-control-(sm|lg)
to .form-control
input
input.form-control.form-control-sm
input.form-control
input.form-control.form-control-lg
select
select.form-control.form-control-sm
select.form-control
select.form-control.form-control-lg
Browser default input
+attribute type="range"
input.form-control-range
+attribute type="range"
(fits to the parent width)
Set readonly
attribute to prevent the modification of the input value (it is still available for copy and paste).
input.form-control
+attribute type="text" value="Read-only value" readonly
With setting .form-control-plaintext
to a form control, it hides borders and shows like a plain text but margins/paddings are preserved.
input.form-control-plaintext
+attribute type="text" value="Read-only value" readonly
form
input.form-control-plaintext
Attributes
type="text"
readonly
value="email@example.com"
form.form-inline
⇒ see Inline form - Example
input.form-control-plaintext
div.form-check
: Stacked (top to bottom) as default Attribute
.form-check-inline
to arrange inline (left to right)input.form-check-input
Attributes
type="checkbox"
or "radio"
id="{control-id}"
checked
.position-static
with no labellabel.form-check-label
Attribute
for="{control-id}"
div.form-check
(×3)
input.form-check-input
Attributes
id="defaultCheck(1|2|3)"
type="checkbox"
value="..."
checked
(first item only)disabled
(last item only)label.form-check-label
Attribute
for="defaultCheck(1|2|3)"
Default checkbox (1|2)
or Disabled checkbox
(grayed automatically)div.form-check
(×3)
input.form-check-input
Attributes
id="exampleRadios(1|2|3)"
type="radio"
name="exampleRadios"
value="..."
checked
(first item only)disabled
(last item only)label.form-check-label
Attribute
for="exampleRadios(1|2|3)"
Default radio (1|2)
or Disabled radio
(grayed automatically)Add .form-check-inline
to div.form-check
Inline checkboxes
Inline radios
div.form-check.form-check-inline
Add .position-static
to input
div.form-check
input.form-check-input.position-static
Attributes
id="blankCheckbox"
type="checkbox"
value="..."
aria-label="Checkbox without label"
div.form-check
(×3)
input.form-check-input.position-static
Attributes
id="blankRadio(1|2|3)"
type="radio"
value="..."
aria-label="Radio button without label"
checked
A control element ( input
, select
, textarea
, etc.) and its associated label label
are set inside div.form-group
form
, orange border to div.form-group
to indicate structureform
More complex and responsive forms can be built using Grid . The first example below divides a row div.row
with two columns div.col
. But it sets slightly wider paddings (gutters) on center.
form
div.row
div.col
(×2)
input.form-control
Changing from.row
to .form-row
adjusts paddings (tighter and compact) for form layouts.
form
div.form-row
div.col
(×2)
From the official document (orange border to .form-group
to indicate structure)
form
div.form-row
div.form-group.col-md-6
: 6/12 (left) on ≥md, stacked on <md
label
Email and input
Emaildiv.form-group.col-md-6
: 6/12 (right) on ≥md, stacked on ≤md
label
Password and input
Passworddiv.form-row
div.form-group.col-md-6
: 6/12 (left) on ≥md, stack on <md
label
City and input
div.form-group.col-md-4
: 4/12 (center) on ≥md, stacked on <md
label
State and select
Choose...div.form-group.col-md-2
: 2/12 (right) on ≥md, stacked on <md
label
Zip and input
.row
to div.form-group
⇒ div.form-group.row
.col-form-label
to label
⇒ label.col-form-label
.col-{breakpoint}-{width}
for responsive layoutform
div.form-group.row
label.col-form-label
Attributes
.col-sm-2
for="inputEmail3"
Email
div.col-sm-10
input.form-control
(same attributes as former examples)fieldset.form-group
div.row
legend.col-form-label
Attributes
.col-sm-2
.pt-0
Radios
div.col-sm-10
div.form-group.row
div.col-sm-2
Checkbox
div.col-sm-10
On horizontal forms, a form control and its corresponding label should have the same sizing.
.col-form-label-(sm|lg)
to (label|legend).col-form-control
.form-control-(sm|lg)
(see Sizing)Left: label.col-form-label.col-form-label-sm
, Right: input.form-control.form-control-sm
Left: label.col-form-label
, Right: input.form-control
Left: label.col-form-label.col-form-label-lg
, Right: input.form-control.form-control-lg
Example using Grid to set column widths.
Structureform
div.form-row
div.col-7
- Form control (City) insidediv.col
- Form control (State) insidediv.col
- Form control (Zip) insideChanging the columns' class from .col
to .col(-sm|-md|-lg|-xl)?-auto
sets widths to browser defaults (⇒ Grid - Variable width content). It can be used for inline layouts.
form
div.form-row.align-items-center
div.col-auto
Attribute
.my-1
label.sr-only
(⇒ Note 2) Attribute
for="inlineFormInput"
Name
input.form-control
Attributes
id="inlineFormInput"
type="text"
placeholder="Jane Doe"
(behaves as an actual label for visible users)div.col-auto
Attribute
.my-1
label.sr-only
Attribute
for="inlineFormInputGroup"
Username
div.input-group
div.col-auto
Attribute
.my-1
div.form-check
input.form-check-input
Attributes
id="autoSizingCheck"
type="checkbox"
label.form-check-label
Attribute
for="autoSizingCheck"
Remember me
div.col-auto
Attribute
.my-1
button.btn.btn-primary
Attribute
type="submit"
Submit
This example is nearly the same as the next Inline form - Basic example. The defference is a behavior below sm breakpoint (<576px). An inline form cancels auto
and switchs to the vertically stacked layout. The example above always fold elements to the next row with auto
.
placeholder
attribute is often used for the role of label with displaying a default value (no label is needed for visible users in this case). But label
should be needed for screenreader users. Utilize .sr-only
(⇒ Screenreaders) for visible uses.An example for responsive behaviors (modified from the official document example).
Structureform
div.form-row.align-items-center
div.col-sm-6.col-md-4.col-lg-3.my-1
+Inside (hidden label + form control)div.col-sm-6.col-md-4.col-lg-3.my-1
+Inside (input group)div.col-auto
+Inside (checkbox)div.col-auto
+Inside (button)It looks same as example 1 on width≥lg (992px). But responsive widths are adjusted for that the form control and the input group has enough widths on sm and md breakpoints.
div.col-sm-3(.my-1)
. But widths (of a form control and a input group) are insufficient on sm and md. Above example adjusts responsive behaviors on all widths.Inline variation with custom form controls (modified from the official document example).
Structureform
div.form-row.align-items-center
div.col-auto
Attribute
.my-1
label
Attributes
.mr-sm-2
for="inlineFormCustomSelect"
Preference
div.col-auto
Attribute
.my-1
select.custom-select
Attributes
.mr-sm-2
id="inlineFormCustomSelect"
style="width: auto;"
(⇒ Note 3 )option ...
div.col-auto
Attribute
.my-1
div.custom-control.custom-checkbox
Attribute
.mr-sm-2
input.custom-control-input
Attributes
id="customControlAutosizing"
type="checkbox"
label.custom-control-label
Attribute
for="customControlAutosizing"
Remember my preference
div.col-auto
Attribute
.my-1
button.btn.btn-primary
Attribute
type="submit"
Submit
select
(width: 100%;
by default). As the result, a custom select
does not arrange inline. This example uses a custom style to fix this problem.(form).form-inline
can be used for inline (horizontal) layouts. It sets layout settings as follows.
display:block
to display:flex
width:100%
to width:auto
auto
. Use Spacing utilities to adjust them.label
for accessibility. Add .sr-only
if it is not needed for visible uses (⇒ Note 2).form.form-inline
label.sr-only
Attribute
for="inlineFormInputName2"
Name
input.form-control
Attributes
.my-1.mr-sm-2
id="inlineFormInputName2"
type="text"
placeholder="Jane Doe"
(actual label for visible users)label.sr-only
Attribute
for="inlineFormInputGroupUsername2"
Username
div.input-group
Attribute
.my-1.mr-sm-2
div.form-check
Attribute
.my-1.mr-sm-2
input.form-check-input
Attributes
id="inlineFormCheck"
type="checkbox"
label.form-check-label
Attribute
for="inlineFormCheck"
Remember me
button.btn.btn-primary
Attributes
.my-1
type="submit"
Submit
.form-check-inline
to a checkbox (or a radio) block div.form-check
. Outer form.form-inline
sets everything for inline checkboxes and radios.form.form-inline
label
Attributes
.my-1.mr-2
for="inlineFormCustomSelectPref"
Preference
select.custom-select
Attribute
.my-1.mr-sm-2
id="inlineFormCustomSelectPref"
option ...
div.custom-control.custom-checkbox
Attributes
.my-1.mr-sm-2
input.custom-control-input
Attributes
id="customControlInline"
type="checkbox"
label.custom-control-label
Attribute
for="customControlInline"
Remember my preference
button.btn.btn-primary
Attributes
.my-1
type="submit"
Submit
Use small.form-text(.text-muted)
for stacked or horizontal layouts. Considering accessibility, a help text should have ID to be referenced by aria-describedby
attribute.
label
Attribute
for="inputPassword5"
Password
input.form-control
Attributes
id="inputPassword5"
type="password"
aria-describedby="passwordHelpBlock"
small.form-text.text-muted
Attribute
id="passwordHelpBlock"
Your password must be 8-20 characters long, ...
Remove .form-text
for inline layouts.
form.form-inline
label
Attribute
for="inputPassword3"
Password
input.form-control
Attributes
.mx-sm-3
id="inputPassword6"
type="password"
aria-describedby="passwordHelpInline"
small.text-muted
Attribute
id="passwordHelpInline"
Must be 8-20 characters long.
You can set the attribute disabled
to disable a control element. You can also wrap control elements with a fieldset
and set disabled
to disable all controls inside (⇒ Note 4).
form
fieldset
Attribute
disabled
disabled
HTML validation was introduced in HTML version 5.0 (see MDN - Form data validation). Now it is supported for all modern browsers (see Can I Use). But browsers' default behaviors are inconsistent and also their validation messages are difficult to recognize for assistive technologies (e.g. screen readers).
Bootstrap has made thier custom validation styles since version 4.0. It is made for improvement of consistency among browsers and message accessibility for assistive technologies.
The example below shows browser default validation behaviors. Note that each behavior heavily varies among browsers (check this example for yourself with various browsers).
Summaryrequired
to all input
s to validate (enables browser's validation)pattern
pattern="[0-9]{5}"
The example below demonstrates Bootstrap 4 style validation.
HTML markups.
HTML summaryform
as below
novalidate
(disables browser default validation).needs-validation
used in this page.form-control
required
(div).valid-feedback
(div).invalid-feedback
Uses Bootstrap 4 CSS validation.
CSS summary.was-validated
to an ancestor (typically a form
)
.form-control
to control elements to validate
.was-validated
to an ancestor and :valid
to itself.was-validated
to an ancestor and :invalid
to itself.valid-feedback
: displays on
.was-validated
to an ancestor:valid
to a former .form-control
.invalid-feedback
: displays on
.was-validated
to an ancestor:invalid
to a former .form-control
Needs JavaScript.
JavaScript summarysubmit
event handler to the corresponding form
(e.g. .needs-validation
){form}.checkValidity()
:valid
pseudo-class to valid controls:invalid
pseudo-class to invalid controlsevent.preventDefault()
event.stopPropagation()
.was-validated
to the form// DOM version (from official document)
(function() {
'use strict';
window.addEventListener('load', function() {
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function(form) {
form.addEventListener('submit', function(event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}, false);
})();
// jQuery version
$('.needs-validation').on('submit', function(event) {
if (!this.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
$(this).addClass('was-validated');
});
Bootstrap also supports for server-side validation behaviors. But pseudo-class :valid
or :invalid
cannot be set from server-side. Bootstrap CSS provides .is-valid
and .is-invalid
for alternatives of corresponding pseudo-classes.
form
(.was-validated
is not needed)
.is-valid
.is-invalid
.valid-feedback
.invalid-feedback
The example below is showing First name and Last name are valid but all others are invalid.
Summaryform
(no class or attribute added).is-valid
to first two form controls (First name, Last name)
.is-invalid
to all other controls
Bootstrap 4 validation supports custom form controls. The example below demonstrates validation behaviors of supported custom form controls.
Settings.was-validated
to form
(demonstrates validating behaviors)required
to controls as below
Changing from .(valid|invalid)-feedback
to .(valid|invalid)-tooltip
displays a validation feedback message as a tooltip popup with translucent background.
div.valid-feedback
⇒ div.valid-tooltip
div.invalid-feedback
⇒ div.invalid-tooltip
Bootstrap 4 custom form controls can be used for further display customization and cross browser consistency.
div.custom-control.custom-checkbox
(×4)
input.custom-control-input
Attributes
id="custom-check-(1|2|3|4)"
type="checkbox"
checked
disabled
label.custom-control-label
Attribute
for="custom-check-(1|2|3|4)"
Custom checkbox (1|2|3|4) (disabled)?
Initial state of the third checkbox is set to - . It is an example of :indeterminate
pseudo-class and set by the following code (JavaScript required).
document.getElementById('custom-check-3').indeterminate = true;
Or using jQuery:
$('#custom-check-3').prop('indeterminate', true);
div.custom-control.custom-radio
(×4)
input.custom-control-input
Attributes
id="custom-radio-(1|2|3|4)"
type="radio"
name="custom-radios"
checked
disabled
label.custom-control-label
Attribute
for="custom-radio-(1|2|3|4)"
Custom radio (1|2|3|4) (disabled)?
div.custom-control.custom-radio.custom-control-inline
(×4)
div.custom-control.custom-switch
(×2)
select.custom-select.custom-select-sm
select.custom-select
select.custom-select.custom-select-lg
On setting attribute multiple
On setting attribute size="3"
As default, range is set to 0..100
, value is set to 50
, step is set to 1
.
label
Attribute
for="customRange1"
Example range
input.custom-range
Attributes
id="customRange1"
type="range"
Set range with min
and max
, value with value
.
label
Attribute
for="customRange2"
Example range
input.custom-range
Attributes
id="customRange2"
type="range"
min="0"
max="5"
value="1"
Set step with step
.
label
Attribute
for="customRange3"
Example range
input.custom-range
Attributes
id="customRange3"
type="range"
min="0"
step="0.5"
max="5"
value="3.5"
div.custom-file
input.custom-file-input
Attributes
id="custom-file"
type="file"
lang="en"
label.custom-file-label
Attribute
for="custom-file"
Choose file
You can change the file browser's default text (Browse on the right) to the arbitrary string.
(≥ 4.2) Adding data-browse="{String}"
to label.custom-file-label
changes the string: English(en), Japanese(ja), and Spanish(es) examples below.
data-browse
attribute.You can control strings with the language attribute lang="{language code}"
(of label.custom-file-label
) by customizing Bootstrap Scss source code (Sass language and node.js development knowledge required). See official document for detail.
You can also control strings with the language attribute by adding some custom CSS (requires only CSS knowledge). If you just want to change to another string, you can append a short CSS as below at the end of <head>
block.
<style>.custom-file-label::after { content: "Choose file"; }</style>
You can also preset multi language settings and choose it by lang
attribute of the input
element (same way as bootstrap.css).
/* en(English) is set as default to bootstrap.css */ /* ja(Japanese) */ .custom-file-input:lang(ja) ~ .custom-file-label::after { content: "ファイル選択"; } /* es(Spanish) */ .custom-file-input:lang(es) ~ .custom-file-label::after { content: "Elegir"; }
Live examples (en/ja/es)
A file browser hides the default input
(by setting opaticy: 0;
) and display the filename with another label
(Choose file...). It is not automatically updated when the user selects a file. JavaScript is needed to update file displays. See the code examples below (code based on jQuery is used in this page).
// DOM example
(function() {
window.addEventListener('load', function() {
var input = document.getElementById('custom-file');
input.addEventListener('change', function(event) {
var label = document.querySelector('[for="custom-file"]');
label.textContent = event.target.files[0].name;
}, false);
}, false);
})();
// jQuery example
$('#custom-file').on('change', function(event) {
$('[for="custom-file"]').text($(this).prop('files')[0].name);
});