mirror of
https://github.com/tenrok/bootstrap.git
synced 2026-06-05 16:42:29 +03:00
v5: Forms update (#28450)
* Initial spike of consolidated form checks * Stub out forms rearrangement - Prepping to drop non-custom file and range inputs - Prepping to merge custom and native checks and radios (with switches) - Prepping to merge custom select with form select - Moving docs arround so forms has it's own area given volume of CSS * Move input group Sass file to forms subdir * Start to split and move the docs around * Simpler imports * Copyediting * delete overview file * Remove commented out code * remove the custom-forms import * rewrite flex-check as form-check, replace all custom properties * Remove old forms doc * stub out new subpage link section * update migration guide * Update nav, forms overview in page nav, and descriptions * fix check bg position * fix margin-top calculation * rename .custom-select to .form-select * Update validation styles for new checks * add some vertical margin, fix inline checks * fix docs examples * better way to do this contents stuff, redo the toc while i'm at it * page restyle for docs while here * un-callout that, edit text * redo padding on toc * fix toc * start to cleanup checks docs * Rewrite Markdown tables into HTML * Redesign tables, redo their docs * Replace Open Iconic icons with custom Bootstrap icons * Redesign the docs navbar, add a subheader, redo the sidebar * Redesign docs homepage a bit * Simplify table style overrides for docs tables * Simplify docs typography for page titles and reading line length * Stub out icons page * Part of sidebar update, remove migration from nav.yml * Move toc CSS to separate partial * Change appearance of overview page * fix sidebar arrow direction * Add footer to docs layout * Update descriptions * Drop the .form-group class for margin utilities * Remove lingering form-group-margin-bottom var * improve footer spacing * add headings to range page * uncomment form range css * Rename .custom-range to .form-range * Drop unused docs var * Uncomment the comment * Remove unused variable * Fix radio image sizing * Reboot update: reset horizontal ul and ol padding * de-dupe IDs * tweak toc styles * nvm, fix dropdown versions stuff * remove sidebar nav toggle for now * broken html * fix more broken html, move css * scss linting * comment out broken helper docs * scope styles * scope styles * Fixes #25540 and fixes #26407 for v5 only * Update sidebar once more * Match new sidenav order * fix syntax error * Rename custom-file to form-file, update paths, update migration docs for previous changes in #28696 * rename back * fix size and alignment * rename that back too
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Checks
|
||||
description: Create consistent cross-browser and cross-device checkboxes and radios with our completely rewritten checks component.
|
||||
group: forms
|
||||
toc: true
|
||||
---
|
||||
|
||||
## Approach
|
||||
|
||||
Browser default checkboxes and radios are replaced with the help of `.form-check`, a series of classes for both input types that improves the layout and behavior of their HTML elements, that provide greater customization and cross browser consistency. Checkboxes are for selecting one or several options in a list, while radios are for selecting one option from many.
|
||||
|
||||
Structurally, our `<input>`s and `<label>`s are sibling elements as opposed to an `<input>` within a `<label>`. This is slightly more verbose as you must specify `id` and `for` attributes to relate the `<input>` and `<label>`. We use the sibling selector (`~`) for all our `<input>` states, like `[checked]` or `[disabled]`. When combined with the `.form-check-label` class, we can easily style the text for each item based on the `<input>`'s state.
|
||||
|
||||
Our checks use custom Bootstrap icons to indicate checked or indeterminate states.
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
var checkbox = document.getElementById("flexCheckIndeterminate");
|
||||
checkbox.indeterminate = true;
|
||||
});
|
||||
</script>
|
||||
|
||||
## Checks
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="" id="flexCheckDefault">
|
||||
<label class="form-check-label" for="flexCheckDefault">
|
||||
Default checkbox
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="" id="flexCheckChecked" checked>
|
||||
<label class="form-check-label" for="flexCheckChecked">
|
||||
Checked checkbox
|
||||
</label>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
### Indeterminate
|
||||
|
||||
Checkboxes can utilize the `:indeterminate` pseudo class when manually set via JavaScript (there is no available HTML attribute for specifying it).
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="" id="flexCheckIndeterminate">
|
||||
<label class="form-check-label" for="flexCheckIndeterminate">
|
||||
Indeterminate checkbox
|
||||
</label>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
### Disabled
|
||||
|
||||
Add the `disabled` attribute and the associated `<label>`s are automatically styled to match with a lighter color to help indicate the input's state.
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="" id="flexCheckDisabled" disabled>
|
||||
<label class="form-check-label" for="flexCheckDisabled">
|
||||
Disabled checkbox
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="" id="flexCheckCheckedDisabled" checked disabled>
|
||||
<label class="form-check-label" for="flexCheckCheckedDisabled">
|
||||
Disabled checked checkbox
|
||||
</label>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
## Radios
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="flexRadioDefault" id="flexRadioDefault1">
|
||||
<label class="form-check-label" for="flexRadioDefault1">
|
||||
Default radio
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="flexRadioDefault" id="flexRadioDefault2" checked>
|
||||
<label class="form-check-label" for="flexRadioDefault2">
|
||||
Default checked radio
|
||||
</label>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
### Disabled
|
||||
|
||||
Add the `disabled` attribute and the associated `<label>`s are automatically styled to match with a lighter color to help indicate the input's state.
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="flexRadioDisabled" id="flexRadioDisabled" disabled>
|
||||
<label class="form-check-label" for="flexRadioDisabled">
|
||||
Disabled radio
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="flexRadioDisabled" id="flexRadioCheckedDisabled" checked disabled>
|
||||
<label class="form-check-label" for="flexRadioCheckedDisabled">
|
||||
Disabled checked radio
|
||||
</label>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
## Switches
|
||||
|
||||
A switch has the markup of a custom checkbox but uses the `.form-switch` class to render a toggle switch. Switches also support the `disabled` attribute.
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="flexSwitchCheckDefault">
|
||||
<label class="form-check-label" for="flexSwitchCheckDefault">Default switch checkbox input</label>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="flexSwitchCheckChecked" checked>
|
||||
<label class="form-check-label" for="flexSwitchCheckChecked">Checked switch checkbox input</label>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="flexSwitchCheckDisabled" disabled>
|
||||
<label class="form-check-label" for="flexSwitchCheckDisabled">Disabled switch checkbox input</label>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="flexSwitchCheckCheckedDisabled" checked disabled>
|
||||
<label class="form-check-label" for="flexSwitchCheckCheckedDisabled">Disabled checked switch checkbox input</label>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
## Default (stacked)
|
||||
|
||||
By default, any number of checkboxes and radios that are immediate sibling will be vertically stacked and appropriately spaced with `.form-check`.
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="" id="defaultCheck1">
|
||||
<label class="form-check-label" for="defaultCheck1">
|
||||
Default checkbox
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="" id="defaultCheck2" disabled>
|
||||
<label class="form-check-label" for="defaultCheck2">
|
||||
Disabled checkbox
|
||||
</label>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios1" value="option1" checked>
|
||||
<label class="form-check-label" for="exampleRadios1">
|
||||
Default radio
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios2" value="option2">
|
||||
<label class="form-check-label" for="exampleRadios2">
|
||||
Second default radio
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios3" value="option3" disabled>
|
||||
<label class="form-check-label" for="exampleRadios3">
|
||||
Disabled radio
|
||||
</label>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
## Inline
|
||||
|
||||
Group checkboxes or radios on the same horizontal row by adding `.form-check-inline` to any `.form-check`.
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" id="inlineCheckbox1" value="option1">
|
||||
<label class="form-check-label" for="inlineCheckbox1">1</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" id="inlineCheckbox2" value="option2">
|
||||
<label class="form-check-label" for="inlineCheckbox2">2</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" id="inlineCheckbox3" value="option3" disabled>
|
||||
<label class="form-check-label" for="inlineCheckbox3">3 (disabled)</label>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio1" value="option1">
|
||||
<label class="form-check-label" for="inlineRadio1">1</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio2" value="option2">
|
||||
<label class="form-check-label" for="inlineRadio2">2</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio3" value="option3" disabled>
|
||||
<label class="form-check-label" for="inlineRadio3">3 (disabled)</label>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
## Without labels
|
||||
|
||||
Add `.position-static` to inputs within `.form-check` that don't have any label text. Remember to still provide some form of label for assistive technologies (for instance, using `aria-label`).
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-check">
|
||||
<input class="form-check-input position-static" type="checkbox" id="blankCheckbox" value="option1" aria-label="...">
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input position-static" type="radio" name="blankRadio" id="blankRadio1" value="option1" aria-label="...">
|
||||
</div>
|
||||
{{< /example >}}
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
layout: docs
|
||||
title: File browser
|
||||
description: Use our custom file inputs for consistent cross-browser styling, built-in customization, and lightweight JavaScript.
|
||||
group: forms
|
||||
toc: false
|
||||
---
|
||||
|
||||
{{< callout info >}}
|
||||
The recommended plugin to animate custom file input: [bs-custom-file-input](https://www.npmjs.com/package/bs-custom-file-input), that's what we are using currently here in our docs.
|
||||
{{< /callout >}}
|
||||
|
||||
The file input is the most gnarly of the bunch and requires additional JavaScript if you'd like to hook them up with functional *Choose file...* and selected file name text.
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-file">
|
||||
<input type="file" class="form-file-input" id="customFile">
|
||||
<label class="form-file-label" for="customFile">
|
||||
<span class="form-file-text">Choose file...</span>
|
||||
<span class="form-file-button">Browse</span>
|
||||
</label>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
Longer placeholder text is truncated and an ellipsis is added when there's not enough space.
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-file">
|
||||
<input type="file" class="form-file-input" id="customFileLong">
|
||||
<label class="form-file-label" for="customFileLong">
|
||||
<span class="form-file-text">Lorem ipsum posuere consectetur est at lobortis nulla vitae elit libero a pharetra augue fusce dapibus tellus ac cursus commodo tortor mauris condimentum nibh ut fermentum massa justo sit amet risus cras mattis consectetur purus sit amet fermentum</span>
|
||||
<span class="form-file-button">Browse</span>
|
||||
</label>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
We hide the default file `<input>` via `opacity` and instead style the `<label>`. The button is generated and positioned with `::after`. Lastly, we declare a `width` and `height` on the `<input>` for proper spacing for surrounding content.
|
||||
@@ -0,0 +1,75 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Form controls
|
||||
description: Give textual form controls like `<input>`s and `<textarea>`s an upgrade with custom styles, sizing, focus states, and more.
|
||||
group: forms
|
||||
toc: true
|
||||
---
|
||||
|
||||
## Example
|
||||
|
||||
{{< example >}}
|
||||
<form>
|
||||
<div class="mb-3">
|
||||
<label for="exampleFormControlInput1">Email address</label>
|
||||
<input type="email" class="form-control" id="exampleFormControlInput1" placeholder="name@example.com">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="exampleFormControlTextarea1">Example textarea</label>
|
||||
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
|
||||
</div>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
## Sizing
|
||||
|
||||
Set heights using classes like `.form-control-lg` and `.form-control-sm`.
|
||||
|
||||
{{< example >}}
|
||||
<input class="form-control form-control-lg" type="text" placeholder=".form-control-lg">
|
||||
<input class="form-control" type="text" placeholder="Default input">
|
||||
<input class="form-control form-control-sm" type="text" placeholder=".form-control-sm">
|
||||
{{< /example >}}
|
||||
|
||||
## Readonly
|
||||
|
||||
Add the `readonly` boolean attribute on an input to prevent modification of the input's value. Read-only inputs appear lighter (just like disabled inputs), but retain the standard cursor.
|
||||
|
||||
{{< example >}}
|
||||
<input class="form-control" type="text" placeholder="Readonly input here..." readonly>
|
||||
{{< /example >}}
|
||||
|
||||
## Readonly plain text
|
||||
|
||||
If you want to have `<input readonly>` elements in your form styled as plain text, use the `.form-control-plaintext` class to remove the default form field styling and preserve the correct margin and padding.
|
||||
|
||||
{{< example >}}
|
||||
<form>
|
||||
<div class="mb-3 row">
|
||||
<label for="staticEmail" class="col-sm-2 col-form-label">Email</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" readonly class="form-control-plaintext" id="staticEmail" value="email@example.com">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 row">
|
||||
<label for="inputPassword" class="col-sm-2 col-form-label">Password</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="password" class="form-control" id="inputPassword">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
{{< example >}}
|
||||
<form class="form-inline">
|
||||
<div class="mb-3 mb-2">
|
||||
<label for="staticEmail2" class="sr-only">Email</label>
|
||||
<input type="text" readonly class="form-control-plaintext" id="staticEmail2" value="email@example.com">
|
||||
</div>
|
||||
<div class="mb-3 mx-sm-3 mb-2">
|
||||
<label for="inputPassword2" class="sr-only">Password</label>
|
||||
<input type="password" class="form-control" id="inputPassword2" placeholder="Password">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary mb-2">Confirm identity</button>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
@@ -0,0 +1,376 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Input group
|
||||
description: Easily extend form controls by adding text, buttons, or button groups on either side of textual inputs, custom selects, and custom file inputs.
|
||||
group: forms
|
||||
toc: true
|
||||
---
|
||||
|
||||
## Basic example
|
||||
|
||||
Place one add-on or button on either side of an input. You may also place one on both sides of an input. Remember to place `<label>`s outside the input group.
|
||||
|
||||
{{< example >}}
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="basic-addon1">@</span>
|
||||
</div>
|
||||
<input type="text" class="form-control" placeholder="Username" aria-label="Username" aria-describedby="basic-addon1">
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<input type="text" class="form-control" placeholder="Recipient's username" aria-label="Recipient's username" aria-describedby="basic-addon2">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text" id="basic-addon2">@example.com</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="basic-url">Your vanity URL</label>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="basic-addon3">https://example.com/users/</span>
|
||||
</div>
|
||||
<input type="text" class="form-control" id="basic-url" aria-describedby="basic-addon3">
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">$</span>
|
||||
</div>
|
||||
<input type="text" class="form-control" aria-label="Amount (to the nearest dollar)">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">.00</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">With textarea</span>
|
||||
</div>
|
||||
<textarea class="form-control" aria-label="With textarea"></textarea>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
## Wrapping
|
||||
|
||||
Input groups wrap by default via `flex-wrap: wrap` in order to accommodate custom form field validation within an input group. You may disable this with `.flex-nowrap`.
|
||||
|
||||
{{< example >}}
|
||||
<div class="input-group flex-nowrap">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="addon-wrapping">@</span>
|
||||
</div>
|
||||
<input type="text" class="form-control" placeholder="Username" aria-label="Username" aria-describedby="addon-wrapping">
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
## Sizing
|
||||
|
||||
Add the relative form sizing classes to the `.input-group` itself and contents within will automatically resize—no need for repeating the form control size classes on each element.
|
||||
|
||||
**Sizing on the individual input group elements isn't supported.**
|
||||
|
||||
{{< example >}}
|
||||
<div class="input-group input-group-sm mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="inputGroup-sizing-sm">Small</span>
|
||||
</div>
|
||||
<input type="text" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-sm">
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="inputGroup-sizing-default">Default</span>
|
||||
</div>
|
||||
<input type="text" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default">
|
||||
</div>
|
||||
|
||||
<div class="input-group input-group-lg">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="inputGroup-sizing-lg">Large</span>
|
||||
</div>
|
||||
<input type="text" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-lg">
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
## Checkboxes and radios
|
||||
|
||||
Place any checkbox or radio option within an input group's addon instead of text.
|
||||
|
||||
{{< example >}}
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">
|
||||
<input type="checkbox" aria-label="Checkbox for following text input">
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" class="form-control" aria-label="Text input with checkbox">
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">
|
||||
<input type="radio" aria-label="Radio button for following text input">
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" class="form-control" aria-label="Text input with radio button">
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
## Multiple inputs
|
||||
|
||||
While multiple `<input>`s are supported visually, validation styles are only available for input groups with a single `<input>`.
|
||||
|
||||
{{< example >}}
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">First and last name</span>
|
||||
</div>
|
||||
<input type="text" aria-label="First name" class="form-control">
|
||||
<input type="text" aria-label="Last name" class="form-control">
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
## Multiple addons
|
||||
|
||||
Multiple add-ons are supported and can be mixed with checkbox and radio input versions.
|
||||
|
||||
{{< example >}}
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">$</span>
|
||||
<span class="input-group-text">0.00</span>
|
||||
</div>
|
||||
<input type="text" class="form-control" aria-label="Dollar amount (with dot and two decimal places)">
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" aria-label="Dollar amount (with dot and two decimal places)">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">$</span>
|
||||
<span class="input-group-text">0.00</span>
|
||||
</div>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
## Button addons
|
||||
|
||||
{{< example >}}
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<button class="btn btn-outline-secondary" type="button" id="button-addon1">Button</button>
|
||||
</div>
|
||||
<input type="text" class="form-control" placeholder="" aria-label="Example text with button addon" aria-describedby="button-addon1">
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<input type="text" class="form-control" placeholder="Recipient's username" aria-label="Recipient's username" aria-describedby="button-addon2">
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-outline-secondary" type="button" id="button-addon2">Button</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend" id="button-addon3">
|
||||
<button class="btn btn-outline-secondary" type="button">Button</button>
|
||||
<button class="btn btn-outline-secondary" type="button">Button</button>
|
||||
</div>
|
||||
<input type="text" class="form-control" placeholder="" aria-label="Example text with two button addons" aria-describedby="button-addon3">
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" placeholder="Recipient's username" aria-label="Recipient's username with two button addons" aria-describedby="button-addon4">
|
||||
<div class="input-group-append" id="button-addon4">
|
||||
<button class="btn btn-outline-secondary" type="button">Button</button>
|
||||
<button class="btn btn-outline-secondary" type="button">Button</button>
|
||||
</div>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
## Buttons with dropdowns
|
||||
|
||||
{{< example >}}
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false">Dropdown</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#">Action</a>
|
||||
<a class="dropdown-item" href="#">Another action</a>
|
||||
<a class="dropdown-item" href="#">Something else here</a>
|
||||
<div role="separator" class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#">Separated link</a>
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" class="form-control" aria-label="Text input with dropdown button">
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" aria-label="Text input with dropdown button">
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false">Dropdown</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#">Action</a>
|
||||
<a class="dropdown-item" href="#">Another action</a>
|
||||
<a class="dropdown-item" href="#">Something else here</a>
|
||||
<div role="separator" class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#">Separated link</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
## Segmented buttons
|
||||
|
||||
{{< example >}}
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<button type="button" class="btn btn-outline-secondary">Action</button>
|
||||
<button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-expanded="false">
|
||||
<span class="sr-only">Toggle Dropdown</span>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#">Action</a>
|
||||
<a class="dropdown-item" href="#">Another action</a>
|
||||
<a class="dropdown-item" href="#">Something else here</a>
|
||||
<div role="separator" class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#">Separated link</a>
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" class="form-control" aria-label="Text input with segmented dropdown button">
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" aria-label="Text input with segmented dropdown button">
|
||||
<div class="input-group-append">
|
||||
<button type="button" class="btn btn-outline-secondary">Action</button>
|
||||
<button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-expanded="false">
|
||||
<span class="sr-only">Toggle Dropdown</span>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#">Action</a>
|
||||
<a class="dropdown-item" href="#">Another action</a>
|
||||
<a class="dropdown-item" href="#">Something else here</a>
|
||||
<div role="separator" class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#">Separated link</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
## Custom forms
|
||||
|
||||
Input groups include support for custom selects and custom file inputs. Browser default versions of these are not supported.
|
||||
|
||||
### Custom select
|
||||
|
||||
{{< example >}}
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<label class="input-group-text" for="inputGroupSelect01">Options</label>
|
||||
</div>
|
||||
<select class="form-select" id="inputGroupSelect01">
|
||||
<option selected>Choose...</option>
|
||||
<option value="1">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<select class="form-select" id="inputGroupSelect02">
|
||||
<option selected>Choose...</option>
|
||||
<option value="1">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
<div class="input-group-append">
|
||||
<label class="input-group-text" for="inputGroupSelect02">Options</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<button class="btn btn-outline-secondary" type="button">Button</button>
|
||||
</div>
|
||||
<select class="form-select" id="inputGroupSelect03" aria-label="Example select with button addon">
|
||||
<option selected>Choose...</option>
|
||||
<option value="1">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<select class="form-select" id="inputGroupSelect04" aria-label="Example select with button addon">
|
||||
<option selected>Choose...</option>
|
||||
<option value="1">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-outline-secondary" type="button">Button</button>
|
||||
</div>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
### Custom file input
|
||||
|
||||
{{< example >}}
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="inputGroupFileAddon01">Upload</span>
|
||||
</div>
|
||||
<div class="form-file">
|
||||
<input type="file" class="form-file-input" id="inputGroupFile01" aria-describedby="inputGroupFileAddon01">
|
||||
<label class="form-file-label" for="inputGroupFile01">
|
||||
<span class="form-file-text">Choose file...</span>
|
||||
<span class="form-file-button">Browse</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<div class="form-file">
|
||||
<input type="file" class="form-file-input" id="inputGroupFile02">
|
||||
<label class="form-file-label" for="inputGroupFile02" aria-describedby="inputGroupFileAddon02">
|
||||
<span class="form-file-text">Choose file...</span>
|
||||
<span class="form-file-button">Browse</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text" id="inputGroupFileAddon02">Upload</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<button class="btn btn-outline-secondary" type="button" id="inputGroupFileAddon03">Button</button>
|
||||
</div>
|
||||
<div class="form-file">
|
||||
<input type="file" class="form-file-input" id="inputGroupFile03" aria-describedby="inputGroupFileAddon03">
|
||||
<label class="form-file-label" for="inputGroupFile03">
|
||||
<span class="form-file-text">Choose file...</span>
|
||||
<span class="form-file-button">Browse</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<div class="form-file">
|
||||
<input type="file" class="form-file-input" id="inputGroupFile04" aria-describedby="inputGroupFileAddon04">
|
||||
<label class="form-file-label" for="inputGroupFile04">
|
||||
<span class="form-file-text">Choose file...</span>
|
||||
<span class="form-file-button">Browse</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-outline-secondary" type="button" id="inputGroupFileAddon04">Button</button>
|
||||
</div>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
## Accessibility
|
||||
|
||||
Screen readers will have trouble with your forms if you don't include a label for every input. For these input groups, ensure that any additional label or functionality is conveyed to assistive technologies.
|
||||
|
||||
The exact technique to be used (`<label>` elements hidden using the `.sr-only` class, or use of the `aria-label` and `aria-labelledby` attributes, possibly in combination with `aria-describedby`) and what additional information will need to be conveyed will vary depending on the exact type of interface widget you're implementing. The examples in this section provide a few suggested, case-specific approaches.
|
||||
@@ -0,0 +1,388 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Layout
|
||||
description: Give your forms some structure—from inline to horizontal to custom grid implementations—with our form layout options.
|
||||
group: forms
|
||||
toc: true
|
||||
---
|
||||
|
||||
## Forms
|
||||
|
||||
Every group of form fields should reside in a `<form>` element. Bootstrap provides no default styling for the `<form>` element, but there are some powerful browser features that are provided by default.
|
||||
|
||||
- New to browser forms? Consider reviewing [the MDN form docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) for an overview and complete list of available attributes.
|
||||
- `<button>`s within a `<form>` default to `type="submit"`, so strive to be specific and always include a `type`.
|
||||
- You can disable every form element within a form with the `disabled` attribute on the `<form>`.
|
||||
|
||||
Since Bootstrap applies `display: block` and `width: 100%` to almost all our form controls, forms will by default stack vertically. Additional classes can be used to vary this layout on a per-form basis.
|
||||
|
||||
## Utilities
|
||||
|
||||
[Margin utilities]({{< docsref "/utilities/spacing" >}}) are the easiest way to add some structure to forms. They provide basic grouping of labels, controls, optional help text, and form validation messaging. We recommend sticking to `margin-bottom` utilities, and using a single direction throughout the form for consistency.
|
||||
|
||||
Feel free to build your forms however you like, with `<fieldset>`s, `<div>`s, or nearly any other element.
|
||||
|
||||
{{< example >}}
|
||||
<form>
|
||||
<div class="mb-3">
|
||||
<label for="formGroupExampleInput">Example label</label>
|
||||
<input type="text" class="form-control" id="formGroupExampleInput" placeholder="Example input placeholder">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="formGroupExampleInput2">Another label</label>
|
||||
<input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Another input placeholder">
|
||||
</div>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
## Form grid
|
||||
|
||||
More complex forms can be built using our grid classes. Use these for form layouts that require multiple columns, varied widths, and additional alignment options. **Requires the `$enable-grid-classes` Sass variable to be enabled** (on by default).
|
||||
|
||||
{{< example >}}
|
||||
<form>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<input type="text" class="form-control" placeholder="First name">
|
||||
</div>
|
||||
<div class="col">
|
||||
<input type="text" class="form-control" placeholder="Last name">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
## Form row
|
||||
|
||||
You may also swap `.row` for `.form-row`, a variation of our standard grid row that overrides the default column gutters for tighter and more compact layouts. **Also requires the `$enable-grid-classes` Sass variable to be enabled** (on by default).
|
||||
|
||||
{{< example >}}
|
||||
<form>
|
||||
<div class="form-row">
|
||||
<div class="col">
|
||||
<input type="text" class="form-control" placeholder="First name">
|
||||
</div>
|
||||
<div class="col">
|
||||
<input type="text" class="form-control" placeholder="Last name">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
More complex layouts can also be created with the grid system.
|
||||
|
||||
{{< example >}}
|
||||
<form>
|
||||
<div class="form-row">
|
||||
<div class="mb-3 col-md-6">
|
||||
<label for="inputEmail4">Email</label>
|
||||
<input type="email" class="form-control" id="inputEmail4">
|
||||
</div>
|
||||
<div class="mb-3 col-md-6">
|
||||
<label for="inputPassword4">Password</label>
|
||||
<input type="password" class="form-control" id="inputPassword4">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="inputAddress">Address</label>
|
||||
<input type="text" class="form-control" id="inputAddress" placeholder="1234 Main St">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="inputAddress2">Address 2</label>
|
||||
<input type="text" class="form-control" id="inputAddress2" placeholder="Apartment, studio, or floor">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="mb-3 col-md-6">
|
||||
<label for="inputCity">City</label>
|
||||
<input type="text" class="form-control" id="inputCity">
|
||||
</div>
|
||||
<div class="mb-3 col-md-4">
|
||||
<label for="inputState">State</label>
|
||||
<select id="inputState" class="form-select">
|
||||
<option selected>Choose...</option>
|
||||
<option>...</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3 col-md-2">
|
||||
<label for="inputZip">Zip</label>
|
||||
<input type="text" class="form-control" id="inputZip">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="gridCheck">
|
||||
<label class="form-check-label" for="gridCheck">
|
||||
Check me out
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Sign in</button>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
## Horizontal form
|
||||
|
||||
Create horizontal forms with the grid by adding the `.row` class to form groups and using the `.col-*-*` classes to specify the width of your labels and controls. Be sure to add `.col-form-label` to your `<label>`s as well so they're vertically centered with their associated form controls.
|
||||
|
||||
At times, you maybe need to use margin or padding utilities to create that perfect alignment you need. For example, we've removed the `padding-top` on our stacked radio inputs label to better align the text baseline.
|
||||
|
||||
{{< example >}}
|
||||
<form>
|
||||
<div class="mb-3 row">
|
||||
<label for="inputEmail3" class="col-sm-2 col-form-label">Email</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="email" class="form-control" id="inputEmail3">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 row">
|
||||
<label for="inputPassword3" class="col-sm-2 col-form-label">Password</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="password" class="form-control" id="inputPassword3">
|
||||
</div>
|
||||
</div>
|
||||
<fieldset class="mb-3">
|
||||
<div class="row">
|
||||
<legend class="col-form-label col-sm-2 pt-0">Radios</legend>
|
||||
<div class="col-sm-10">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="gridRadios" id="gridRadios1" value="option1" checked>
|
||||
<label class="form-check-label" for="gridRadios1">
|
||||
First radio
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="gridRadios" id="gridRadios2" value="option2">
|
||||
<label class="form-check-label" for="gridRadios2">
|
||||
Second radio
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check disabled">
|
||||
<input class="form-check-input" type="radio" name="gridRadios" id="gridRadios3" value="option3" disabled>
|
||||
<label class="form-check-label" for="gridRadios3">
|
||||
Third disabled radio
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="mb-3 row">
|
||||
<div class="col-sm-2">Checkbox</div>
|
||||
<div class="col-sm-10">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="gridCheck1">
|
||||
<label class="form-check-label" for="gridCheck1">
|
||||
Example checkbox
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 row">
|
||||
<div class="col-sm-10">
|
||||
<button type="submit" class="btn btn-primary">Sign in</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
### Horizontal form label sizing
|
||||
|
||||
Be sure to use `.col-form-label-sm` or `.col-form-label-lg` to your `<label>`s or `<legend>`s to correctly follow the size of `.form-control-lg` and `.form-control-sm`.
|
||||
|
||||
{{< example >}}
|
||||
<form>
|
||||
<div class="mb-3 row">
|
||||
<label for="colFormLabelSm" class="col-sm-2 col-form-label col-form-label-sm">Email</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="email" class="form-control form-control-sm" id="colFormLabelSm" placeholder="col-form-label-sm">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 row">
|
||||
<label for="colFormLabel" class="col-sm-2 col-form-label">Email</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="email" class="form-control" id="colFormLabel" placeholder="col-form-label">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 row">
|
||||
<label for="colFormLabelLg" class="col-sm-2 col-form-label col-form-label-lg">Email</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="email" class="form-control form-control-lg" id="colFormLabelLg" placeholder="col-form-label-lg">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
## Column sizing
|
||||
|
||||
As shown in the previous examples, our grid system allows you to place any number of `.col`s within a `.row` or `.form-row`. They'll split the available width equally between them. You may also pick a subset of your columns to take up more or less space, while the remaining `.col`s equally split the rest, with specific column classes like `.col-7`.
|
||||
|
||||
{{< example >}}
|
||||
<form>
|
||||
<div class="form-row">
|
||||
<div class="col-7">
|
||||
<input type="text" class="form-control" placeholder="City">
|
||||
</div>
|
||||
<div class="col">
|
||||
<input type="text" class="form-control" placeholder="State">
|
||||
</div>
|
||||
<div class="col">
|
||||
<input type="text" class="form-control" placeholder="Zip">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
## Auto-sizing
|
||||
|
||||
The example below uses a flexbox utility to vertically center the contents and changes `.col` to `.col-auto` so that your columns only take up as much space as needed. Put another way, the column sizes itself based on the contents.
|
||||
|
||||
{{< example >}}
|
||||
<form>
|
||||
<div class="form-row align-items-center">
|
||||
<div class="col-auto">
|
||||
<label class="sr-only" for="inlineFormInput">Name</label>
|
||||
<input type="text" class="form-control mb-2" id="inlineFormInput" placeholder="Jane Doe">
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label class="sr-only" for="inlineFormInputGroup">Username</label>
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">@</div>
|
||||
</div>
|
||||
<input type="text" class="form-control" id="inlineFormInputGroup" placeholder="Username">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="form-check mb-2">
|
||||
<input class="form-check-input" type="checkbox" id="autoSizingCheck">
|
||||
<label class="form-check-label" for="autoSizingCheck">
|
||||
Remember me
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button type="submit" class="btn btn-primary mb-2">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
You can then remix that once again with size-specific column classes.
|
||||
|
||||
{{< example >}}
|
||||
<form>
|
||||
<div class="form-row align-items-center">
|
||||
<div class="col-sm-3 my-1">
|
||||
<label class="sr-only" for="inlineFormInputName">Name</label>
|
||||
<input type="text" class="form-control" id="inlineFormInputName" placeholder="Jane Doe">
|
||||
</div>
|
||||
<div class="col-sm-3 my-1">
|
||||
<label class="sr-only" for="inlineFormInputGroupUsername">Username</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">@</div>
|
||||
</div>
|
||||
<input type="text" class="form-control" id="inlineFormInputGroupUsername" placeholder="Username">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto my-1">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="autoSizingCheck2">
|
||||
<label class="form-check-label" for="autoSizingCheck2">
|
||||
Remember me
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto my-1">
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
And of course [custom form controls](#custom-forms) are supported.
|
||||
|
||||
{{< example >}}
|
||||
<form>
|
||||
<div class="form-row align-items-center">
|
||||
<div class="col-auto my-1">
|
||||
<label class="mr-sm-2 sr-only" for="inlineFormSelect">Preference</label>
|
||||
<select class="form-select mr-sm-2" id="inlineFormSelect">
|
||||
<option selected>Choose...</option>
|
||||
<option value="1">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-auto my-1">
|
||||
<div class="form-check mr-sm-2">
|
||||
<input type="checkbox" class="form-check-input" id="formCheckAutosizing">
|
||||
<label class="form-check-label" for="formCheckAutosizing">Remember my preference</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto my-1">
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
## Inline forms
|
||||
|
||||
Use the `.form-inline` class to display a series of labels, form controls, and buttons on a single horizontal row. Form controls within inline forms vary slightly from their default states.
|
||||
|
||||
- Controls are `display: flex`, collapsing any HTML white space and allowing you to provide alignment control with [spacing]({{< docsref "/utilities/spacing" >}}) and [flexbox]({{< docsref "/utilities/flex" >}}) utilities.
|
||||
- Controls and input groups receive `width: auto` to override the Bootstrap default `width: 100%`.
|
||||
- Controls **only appear inline in viewports that are at least 576px wide** to account for narrow viewports on mobile devices.
|
||||
|
||||
You may need to manually address the width and alignment of individual form controls with [spacing utilities]({{< docsref "/utilities/spacing" >}}) (as shown below). Lastly, be sure to always include a `<label>` with each form control, even if you need to hide it from non-screenreader visitors with `.sr-only`.
|
||||
|
||||
{{< example >}}
|
||||
<form class="form-inline">
|
||||
<label class="sr-only" for="inlineFormInputName2">Name</label>
|
||||
<input type="text" class="form-control mb-2 mr-sm-2" id="inlineFormInputName2" placeholder="Jane Doe">
|
||||
|
||||
<label class="sr-only" for="inlineFormInputGroupUsername2">Username</label>
|
||||
<div class="input-group mb-2 mr-sm-2">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">@</div>
|
||||
</div>
|
||||
<input type="text" class="form-control" id="inlineFormInputGroupUsername2" placeholder="Username">
|
||||
</div>
|
||||
|
||||
<div class="form-check mb-2 mr-sm-2">
|
||||
<input class="form-check-input" type="checkbox" id="inlineFormCheck">
|
||||
<label class="form-check-label" for="inlineFormCheck">
|
||||
Remember me
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary mb-2">Submit</button>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
Custom form controls and selects are also supported.
|
||||
|
||||
{{< example >}}
|
||||
<form class="form-inline">
|
||||
<label class="my-1 mr-2" for="inlineFormSelectPref">Preference</label>
|
||||
<select class="form-select my-1 mr-sm-2" id="inlineFormSelectPref">
|
||||
<option selected>Choose...</option>
|
||||
<option value="1">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
|
||||
<div class="form-check my-1 mr-sm-2">
|
||||
<input type="checkbox" class="form-check-input" id="formCheckInline">
|
||||
<label class="form-check-label" for="formCheckInline">Remember my preference</label>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary my-1">Submit</button>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
{{< callout warning >}}
|
||||
### Alternatives to hidden labels
|
||||
|
||||
Assistive technologies such as screen readers will have trouble with your forms if you don't include a label for every input. For these inline forms, you can hide the labels using the `.sr-only` class. There are further alternative methods of providing a label for assistive technologies, such as the `aria-label`, `aria-labelledby` or `title` attribute. If none of these are present, assistive technologies may resort to using the `placeholder` attribute, if present, but note that use of `placeholder` as a replacement for other labelling methods is not advised.
|
||||
{{< /callout >}}
|
||||
@@ -0,0 +1,123 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Forms
|
||||
description: Examples and usage guidelines for form control styles, layout options, and custom components for creating a wide variety of forms.
|
||||
group: forms
|
||||
toc: true
|
||||
sections:
|
||||
- title: Form control
|
||||
description: Style textual inputs and textareas with support for multiple states.
|
||||
- title: Select
|
||||
description: Improve browser default select elements with a custom initial appearance.
|
||||
- title: Checks
|
||||
description: Use our custom radio buttons and checkboxes in forms for selecting input options.
|
||||
- title: File
|
||||
description: Replace browser default file inputs with our custom version with optional JavaScript.
|
||||
- title: Range
|
||||
description: Replace browser default range inputs with our custom version.
|
||||
- title: Input group
|
||||
description: Attach labels and buttons to your inputs for increased semantic value.
|
||||
- title: Layout
|
||||
description: Create inline, horizontal, or complex grid-based layouts with your forms.
|
||||
- title: Validation
|
||||
description: Validate your forms with custom or native validation behaviors and styles.
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Bootstrap's form controls expand on [our Rebooted form styles]({{< docsref "/content/reboot#forms" >}}) with classes. Use these classes to opt into their customized displays for a more consistent rendering across browsers and devices.
|
||||
|
||||
Be sure to use an appropriate `type` attribute on all inputs (e.g., `email` for email address or `number` for numerical information) to take advantage of newer input controls like email verification, number selection, and more.
|
||||
|
||||
Here's a quick example to demonstrate Bootstrap's form styles. Keep reading for documentation on required classes, form layout, and more.
|
||||
|
||||
{{< example >}}
|
||||
<form>
|
||||
<div class="mb-3">
|
||||
<label for="exampleInputEmail1">Email address</label>
|
||||
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp">
|
||||
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="exampleInputPassword1">Password</label>
|
||||
<input type="password" class="form-control" id="exampleInputPassword1">
|
||||
</div>
|
||||
<div class="mb-3 form-check">
|
||||
<input type="checkbox" class="form-check-input" id="exampleCheck1">
|
||||
<label class="form-check-label" for="exampleCheck1">Check me out</label>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
## Help text
|
||||
|
||||
Block-level help text in forms can be created using `.form-text` (previously known as `.help-block` in v3). Inline help text can be flexibly implemented using any inline HTML element and utility classes like `.text-muted`.
|
||||
|
||||
{{< callout warning >}}
|
||||
##### Associating help text with form controls
|
||||
|
||||
Help text should be explicitly associated with the form control it relates to using the `aria-describedby` attribute. This will ensure that assistive technologies—such as screen readers—will announce this help text when the user focuses or enters the control.
|
||||
{{< /callout >}}
|
||||
|
||||
Help text below inputs can be styled with `.form-text`. This class includes `display: block` and adds some top margin for easy spacing from the inputs above.
|
||||
|
||||
{{< example >}}
|
||||
<label for="inputPassword5">Password</label>
|
||||
<input type="password" id="inputPassword5" class="form-control" aria-describedby="passwordHelpBlock">
|
||||
<small id="passwordHelpBlock" class="form-text text-muted">
|
||||
Your password must be 8-20 characters long, contain letters and numbers, and must not contain spaces, special characters, or emoji.
|
||||
</small>
|
||||
{{< /example >}}
|
||||
|
||||
Inline text can use any typical inline HTML element (be it a `<small>`, `<span>`, or something else) with nothing more than a utility class.
|
||||
|
||||
{{< example >}}
|
||||
<form class="form-inline">
|
||||
<div class="mb-3">
|
||||
<label for="inputPassword6">Password</label>
|
||||
<input type="password" id="inputPassword6" class="form-control mx-sm-3" aria-describedby="passwordHelpInline">
|
||||
<small id="passwordHelpInline" class="text-muted">
|
||||
Must be 8-20 characters long.
|
||||
</small>
|
||||
</div>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
## Disabled forms
|
||||
|
||||
Add the `disabled` boolean attribute on an input to prevent user interactions and make it appear lighter.
|
||||
|
||||
{{< highlight html >}}
|
||||
<input class="form-control" id="disabledInput" type="text" placeholder="Disabled input here..." disabled>
|
||||
{{< /highlight >}}
|
||||
|
||||
Add the `disabled` attribute to a `<fieldset>` to disable all the controls within.
|
||||
|
||||
By default, browsers will treat all native form controls (`<input>`, `<select>`, and `<button>` elements) inside a `<fieldset disabled>` as disabled, preventing both keyboard and mouse interactions on them. However, if your form also includes `<a ... class="btn btn-*">` elements, these will only be given a style of `pointer-events: none`.
|
||||
|
||||
{{< example >}}
|
||||
<form>
|
||||
<fieldset disabled>
|
||||
<div class="mb-3">
|
||||
<label for="disabledTextInput">Disabled input</label>
|
||||
<input type="text" id="disabledTextInput" class="form-control" placeholder="Disabled input">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="disabledSelect">Disabled select menu</label>
|
||||
<select id="disabledSelect" class="form-select">
|
||||
<option>Disabled select</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="disabledFieldsetCheck" disabled>
|
||||
<label class="form-check-label" for="disabledFieldsetCheck">
|
||||
Can't check this
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Range
|
||||
description: Use our custom range inputs for consistent cross-browser styling and built-in customization.
|
||||
group: forms
|
||||
toc: true
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Create custom `<input type="range">` controls with `.form-range`. The track (the background) and thumb (the value) are both styled to appear the same across browsers. As only Firefox supports "filling" their track from the left or right of the thumb as a means to visually indicate progress, we do not currently support it.
|
||||
|
||||
{{< example >}}
|
||||
<label for="customRange1">Example range</label>
|
||||
<input type="range" class="form-range" id="customRange1">
|
||||
{{< /example >}}
|
||||
|
||||
## Min and max
|
||||
|
||||
Range inputs have implicit values for `min` and `max`—`0` and `100`, respectively. You may specify new values for those using the `min` and `max` attributes.
|
||||
|
||||
{{< example >}}
|
||||
<label for="customRange2">Example range</label>
|
||||
<input type="range" class="form-range" min="0" max="5" id="customRange2">
|
||||
{{< /example >}}
|
||||
|
||||
## Steps
|
||||
|
||||
By default, range inputs "snap" to integer values. To change this, you can specify a `step` value. In the example below, we double the number of steps by using `step="0.5"`.
|
||||
|
||||
{{< example >}}
|
||||
<label for="customRange3">Example range</label>
|
||||
<input type="range" class="form-range" min="0" max="5" step="0.5" id="customRange3">
|
||||
{{< /example >}}
|
||||
@@ -0,0 +1,62 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Select
|
||||
description: Customize the native `<select>`s with custom CSS that changes the element's initial appearance.
|
||||
group: forms
|
||||
toc: true
|
||||
---
|
||||
|
||||
## Default
|
||||
|
||||
Custom `<select>` menus need only a custom class, `.form-select` to trigger the custom styles. Custom styles are limited to the `<select>`'s initial appearance and cannot modify the `<option>`s due to browser limitations.
|
||||
|
||||
{{< example >}}
|
||||
<select class="form-select">
|
||||
<option selected>Open this select menu</option>
|
||||
<option value="1">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
{{< /example >}}
|
||||
|
||||
## Sizing
|
||||
|
||||
You may also choose from small and large custom selects to match our similarly sized text inputs.
|
||||
|
||||
{{< example >}}
|
||||
<select class="form-select form-select-lg mb-3">
|
||||
<option selected>Open this select menu</option>
|
||||
<option value="1">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
|
||||
<select class="form-select form-select-sm">
|
||||
<option selected>Open this select menu</option>
|
||||
<option value="1">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
{{< /example >}}
|
||||
|
||||
The `multiple` attribute is also supported:
|
||||
|
||||
{{< example >}}
|
||||
<select class="form-select" multiple>
|
||||
<option selected>Open this select menu</option>
|
||||
<option value="1">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
{{< /example >}}
|
||||
|
||||
As is the `size` attribute:
|
||||
|
||||
{{< example >}}
|
||||
<select class="form-select" size="3">
|
||||
<option selected>Open this select menu</option>
|
||||
<option value="1">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
{{< /example >}}
|
||||
@@ -0,0 +1,404 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Validation
|
||||
description: Provide valuable, actionable feedback to your users with HTML5 form validation, via browser default behaviors or custom styles and JavaScript.
|
||||
group: forms
|
||||
toc: true
|
||||
---
|
||||
|
||||
{{< callout warning >}}
|
||||
We currently recommend using custom validation styles, as native browser default validation messages are not consistently exposed to assistive technologies in all browsers (most notably, Chrome on desktop and mobile).
|
||||
{{< /callout >}}
|
||||
|
||||
## How it works
|
||||
|
||||
Here's how form validation works with Bootstrap:
|
||||
|
||||
- HTML form validation is applied via CSS's two pseudo-classes, `:invalid` and `:valid`. It applies to `<input>`, `<select>`, and `<textarea>` elements.
|
||||
- Bootstrap scopes the `:invalid` and `:valid` styles to parent `.was-validated` class, usually applied to the `<form>`. Otherwise, any required field without a value shows up as invalid on page load. This way, you may choose when to activate them (typically after form submission is attempted).
|
||||
- To reset the appearance of the form (for instance, in the case of dynamic form submissions using AJAX), remove the `.was-validated` class from the `<form>` again after submission.
|
||||
- As a fallback, `.is-invalid` and `.is-valid` classes may be used instead of the pseudo-classes for [server-side validation](#server-side). They do not require a `.was-validated` parent class.
|
||||
- Due to constraints in how CSS works, we cannot (at present) apply styles to a `<label>` that comes before a form control in the DOM without the help of custom JavaScript.
|
||||
- All modern browsers support the [constraint validation API](https://www.w3.org/TR/html5/sec-forms.html#the-constraint-validation-api), a series of JavaScript methods for validating form controls.
|
||||
- Feedback messages may utilize the [browser defaults](#browser-defaults) (different for each browser, and unstylable via CSS) or our custom feedback styles with additional HTML and CSS.
|
||||
- You may provide custom validity messages with `setCustomValidity` in JavaScript.
|
||||
|
||||
With that in mind, consider the following demos for our custom form validation styles, optional server-side classes, and browser defaults.
|
||||
|
||||
## Custom styles
|
||||
|
||||
For custom Bootstrap form validation messages, you'll need to add the `novalidate` boolean attribute to your `<form>`. This disables the browser default feedback tooltips, but still provides access to the form validation APIs in JavaScript. Try to submit the form below; our JavaScript will intercept the submit button and relay feedback to you. When attempting to submit, you'll see the `:invalid` and `:valid` styles applied to your form controls.
|
||||
|
||||
Custom feedback styles apply custom colors, borders, focus styles, and background icons to better communicate feedback. Background icons for `<select>`s are only available with `.form-select`, and not `.form-control`.
|
||||
|
||||
{{< example >}}
|
||||
<form class="needs-validation" novalidate>
|
||||
<div class="form-row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="validationCustom01">First name</label>
|
||||
<input type="text" class="form-control" id="validationCustom01" value="Mark" required>
|
||||
<div class="valid-feedback">
|
||||
Looks good!
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="validationCustom02">Last name</label>
|
||||
<input type="text" class="form-control" id="validationCustom02" value="Otto" required>
|
||||
<div class="valid-feedback">
|
||||
Looks good!
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="validationCustomUsername">Username</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="inputGroupPrepend">@</span>
|
||||
</div>
|
||||
<input type="text" class="form-control" id="validationCustomUsername" aria-describedby="inputGroupPrepend" required>
|
||||
<div class="invalid-feedback">
|
||||
Please choose a username.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="validationCustom03">City</label>
|
||||
<input type="text" class="form-control" id="validationCustom03" required>
|
||||
<div class="invalid-feedback">
|
||||
Please provide a valid city.
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<label for="validationCustom04">State</label>
|
||||
<select class="form-select" id="validationCustom04" required>
|
||||
<option selected disabled value="">Choose...</option>
|
||||
<option>...</option>
|
||||
</select>
|
||||
<div class="invalid-feedback">
|
||||
Please select a valid state.
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<label for="validationCustom05">Zip</label>
|
||||
<input type="text" class="form-control" id="validationCustom05" required>
|
||||
<div class="invalid-feedback">
|
||||
Please provide a valid zip.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="" id="invalidCheck" required>
|
||||
<label class="form-check-label" for="invalidCheck">
|
||||
Agree to terms and conditions
|
||||
</label>
|
||||
<div class="invalid-feedback">
|
||||
You must agree before submitting.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-primary" type="submit">Submit form</button>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
// Example starter JavaScript for disabling form submissions if there are invalid fields
|
||||
(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);
|
||||
})();
|
||||
</script>
|
||||
{{< /example >}}
|
||||
|
||||
## Browser defaults
|
||||
|
||||
Not interested in custom validation feedback messages or writing JavaScript to change form behaviors? All good, you can use the browser defaults. Try submitting the form below. Depending on your browser and OS, you'll see a slightly different style of feedback.
|
||||
|
||||
While these feedback styles cannot be styled with CSS, you can still customize the feedback text through JavaScript.
|
||||
|
||||
{{< example >}}
|
||||
<form>
|
||||
<div class="form-row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="validationDefault01">First name</label>
|
||||
<input type="text" class="form-control" id="validationDefault01" value="Mark" required>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="validationDefault02">Last name</label>
|
||||
<input type="text" class="form-control" id="validationDefault02" value="Otto" required>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="validationDefaultUsername">Username</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="inputGroupPrepend2">@</span>
|
||||
</div>
|
||||
<input type="text" class="form-control" id="validationDefaultUsername" aria-describedby="inputGroupPrepend2" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="validationDefault03">City</label>
|
||||
<input type="text" class="form-control" id="validationDefault03" required>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<label for="validationDefault04">State</label>
|
||||
<select class="form-select" id="validationDefault04" required>
|
||||
<option selected disabled value="">Choose...</option>
|
||||
<option>...</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<label for="validationDefault05">Zip</label>
|
||||
<input type="text" class="form-control" id="validationDefault05" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="" id="invalidCheck2" required>
|
||||
<label class="form-check-label" for="invalidCheck2">
|
||||
Agree to terms and conditions
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-primary" type="submit">Submit form</button>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
## Server side
|
||||
|
||||
We recommend using client-side validation, but in case you require server-side validation, you can indicate invalid and valid form fields with `.is-invalid` and `.is-valid`. Note that `.invalid-feedback` is also supported with these classes.
|
||||
|
||||
{{< example >}}
|
||||
<form>
|
||||
<div class="form-row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="validationServer01">First name</label>
|
||||
<input type="text" class="form-control is-valid" id="validationServer01" value="Mark" required>
|
||||
<div class="valid-feedback">
|
||||
Looks good!
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="validationServer02">Last name</label>
|
||||
<input type="text" class="form-control is-valid" id="validationServer02" value="Otto" required>
|
||||
<div class="valid-feedback">
|
||||
Looks good!
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="validationServerUsername">Username</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="inputGroupPrepend3">@</span>
|
||||
</div>
|
||||
<input type="text" class="form-control is-invalid" id="validationServerUsername" aria-describedby="inputGroupPrepend3" required>
|
||||
<div class="invalid-feedback">
|
||||
Please choose a username.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="validationServer03">City</label>
|
||||
<input type="text" class="form-control is-invalid" id="validationServer03" required>
|
||||
<div class="invalid-feedback">
|
||||
Please provide a valid city.
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<label for="validationServer04">State</label>
|
||||
<select class="form-select is-invalid" id="validationServer04" required>
|
||||
<option selected disabled value="">Choose...</option>
|
||||
<option>...</option>
|
||||
</select>
|
||||
<div class="invalid-feedback">
|
||||
Please select a valid state.
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<label for="validationServer05">Zip</label>
|
||||
<input type="text" class="form-control is-invalid" id="validationServer05" required>
|
||||
<div class="invalid-feedback">
|
||||
Please provide a valid zip.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input is-invalid" type="checkbox" value="" id="invalidCheck3" required>
|
||||
<label class="form-check-label" for="invalidCheck3">
|
||||
Agree to terms and conditions
|
||||
</label>
|
||||
<div class="invalid-feedback">
|
||||
You must agree before submitting.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-primary" type="submit">Submit form</button>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
## Supported elements
|
||||
|
||||
Validation styles are available for the following form controls and components:
|
||||
|
||||
- `<input>`s and `<textarea>`s with `.form-control` (including up to one `.form-control` in input groups)
|
||||
- `<select>`s with `.form-control` or `.form-select`
|
||||
- `.form-check`s
|
||||
- `.custom-checkbox`s and `.custom-radio`s
|
||||
- `.form-file`
|
||||
|
||||
{{< example >}}
|
||||
<form class="was-validated">
|
||||
<div class="mb-3">
|
||||
<label for="validationTextarea">Textarea</label>
|
||||
<textarea class="form-control is-invalid" id="validationTextarea" placeholder="Required example textarea" required></textarea>
|
||||
<div class="invalid-feedback">
|
||||
Please enter a message in the textarea.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="custom-control custom-checkbox mb-3">
|
||||
<input type="checkbox" class="custom-control-input" id="customControlValidation1" required>
|
||||
<label class="custom-control-label" for="customControlValidation1">Check this custom checkbox</label>
|
||||
<div class="invalid-feedback">Example invalid feedback text</div>
|
||||
</div>
|
||||
|
||||
<div class="custom-control custom-radio">
|
||||
<input type="radio" class="custom-control-input" id="customControlValidation2" name="radio-stacked" required>
|
||||
<label class="custom-control-label" for="customControlValidation2">Toggle this custom radio</label>
|
||||
</div>
|
||||
<div class="custom-control custom-radio mb-3">
|
||||
<input type="radio" class="custom-control-input" id="customControlValidation3" name="radio-stacked" required>
|
||||
<label class="custom-control-label" for="customControlValidation3">Or toggle this other custom radio</label>
|
||||
<div class="invalid-feedback">More example invalid feedback text</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<select class="form-select" required>
|
||||
<option value="">Open this select menu</option>
|
||||
<option value="1">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
<div class="invalid-feedback">Example invalid custom select feedback</div>
|
||||
</div>
|
||||
|
||||
<div class="form-file">
|
||||
<input type="file" class="form-file-input" id="validatedCustomFile" required>
|
||||
<label class="form-file-label" for="validatedCustomFile">Choose file...</label>
|
||||
<div class="invalid-feedback">Example invalid custom file feedback</div>
|
||||
</div>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
## Tooltips
|
||||
|
||||
If your form layout allows it, you can swap the `.{valid|invalid}-feedback` classes for `.{valid|invalid}-tooltip` classes to display validation feedback in a styled tooltip. Be sure to have a parent with `position: relative` on it for tooltip positioning. In the example below, our column classes have this already, but your project may require an alternative setup.
|
||||
|
||||
{{< example >}}
|
||||
<form class="needs-validation" novalidate>
|
||||
<div class="form-row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="validationTooltip01">First name</label>
|
||||
<input type="text" class="form-control" id="validationTooltip01" value="Mark" required>
|
||||
<div class="valid-tooltip">
|
||||
Looks good!
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="validationTooltip02">Last name</label>
|
||||
<input type="text" class="form-control" id="validationTooltip02" value="Otto" required>
|
||||
<div class="valid-tooltip">
|
||||
Looks good!
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="validationTooltipUsername">Username</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="validationTooltipUsernamePrepend">@</span>
|
||||
</div>
|
||||
<input type="text" class="form-control" id="validationTooltipUsername" aria-describedby="validationTooltipUsernamePrepend" required>
|
||||
<div class="invalid-tooltip">
|
||||
Please choose a unique and valid username.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="validationTooltip03">City</label>
|
||||
<input type="text" class="form-control" id="validationTooltip03" required>
|
||||
<div class="invalid-tooltip">
|
||||
Please provide a valid city.
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<label for="validationTooltip04">State</label>
|
||||
<select class="form-select" id="validationTooltip04" required>
|
||||
<option selected disabled value="">Choose...</option>
|
||||
<option>...</option>
|
||||
</select>
|
||||
<div class="invalid-tooltip">
|
||||
Please select a valid state.
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<label for="validationTooltip05">Zip</label>
|
||||
<input type="text" class="form-control" id="validationTooltip05" required>
|
||||
<div class="invalid-tooltip">
|
||||
Please provide a valid zip.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-primary" type="submit">Submit form</button>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
## Customizing
|
||||
|
||||
Validation states can be customized via Sass with the `$form-validation-states` map. Located in our `_variables.scss` file, this Sass map is looped over to generate the default `valid`/`invalid` validation states. Included is a nested map for customizing each state's color and icon. While no other states are supported by browsers, those using custom styles can easily add more complex form feedback.
|
||||
|
||||
Please note that we do not recommend customizing these values without also modifying the `form-validation-state` mixin.
|
||||
|
||||
{{< highlight scss >}}
|
||||
// Sass map from `_variables.scss`
|
||||
// Override this and recompile your Sass to generate different states
|
||||
$form-validation-states: map-merge(
|
||||
(
|
||||
"valid": (
|
||||
"color": $form-feedback-valid-color,
|
||||
"icon": $form-feedback-icon-valid
|
||||
),
|
||||
"invalid": (
|
||||
"color": $form-feedback-invalid-color,
|
||||
"icon": $form-feedback-icon-invalid
|
||||
)
|
||||
),
|
||||
$form-validation-states
|
||||
);
|
||||
|
||||
// Loop from `_forms.scss`
|
||||
// Any modifications to the above Sass map will be reflected in your compiled
|
||||
// CSS via this loop.
|
||||
@each $state, $data in $form-validation-states {
|
||||
@include form-validation-state($state, map-get($data, color), map-get($data, icon));
|
||||
}
|
||||
{{< /highlight >}}
|
||||
Reference in New Issue
Block a user