aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorMark Otto <[email protected]>2017-06-14 20:45:31 -0700
committerGitHub <[email protected]>2017-06-14 20:45:31 -0700
commit5818374fdf55db9b2437391a68af3f057a992fbe (patch)
tree057218e9ed7a7442459d36b40004f6f7e188cf0f /docs
parentaa8c456a16b83ed041709b45b068788ec2d4d0d4 (diff)
parent2e798301ca15ed45c86283371d4c5a37510f945d (diff)
downloadbootstrap-5818374fdf55db9b2437391a68af3f057a992fbe.tar.xz
bootstrap-5818374fdf55db9b2437391a68af3f057a992fbe.zip
Merge branch 'v4-dev' into rip-custom
Diffstat (limited to 'docs')
-rw-r--r--docs/4.0/components/collapse.md31
-rw-r--r--docs/4.0/components/dropdowns.md2
-rw-r--r--docs/4.0/components/forms.md1132
-rw-r--r--docs/4.0/components/popovers.md2
-rw-r--r--docs/4.0/components/tooltips.md2
-rw-r--r--docs/4.0/examples/album/index.html2
-rw-r--r--docs/4.0/examples/blog/index.html2
-rw-r--r--docs/4.0/examples/carousel/index.html2
-rw-r--r--docs/4.0/examples/cover/index.html2
-rw-r--r--docs/4.0/examples/dashboard/index.html2
-rw-r--r--docs/4.0/examples/jumbotron/index.html2
-rw-r--r--docs/4.0/examples/justified-nav/index.html2
-rw-r--r--docs/4.0/examples/navbar-top-fixed/index.html2
-rw-r--r--docs/4.0/examples/navbar-top/index.html2
-rw-r--r--docs/4.0/examples/navbars/index.html2
-rw-r--r--docs/4.0/examples/offcanvas/index.html2
-rw-r--r--docs/4.0/examples/starter-template/index.html2
-rw-r--r--docs/4.0/examples/sticky-footer-navbar/index.html2
-rw-r--r--docs/4.0/examples/tooltip-viewport/index.html2
-rw-r--r--docs/4.0/migration.md3
20 files changed, 636 insertions, 564 deletions
diff --git a/docs/4.0/components/collapse.md b/docs/4.0/components/collapse.md
index cbdc50bb7..e1d3e3b64 100644
--- a/docs/4.0/components/collapse.md
+++ b/docs/4.0/components/collapse.md
@@ -32,6 +32,35 @@ You can use a link with the `href` attribute, or a button with the `data-target`
</div>
{% endexample %}
+## Multiple triggers / targets
+
+A `<button>` or `<a>` can show and hide multiple elements by referencing them with a JQuery selector in its `href` or `data-target` attribute.
+Multiple `<button>` or `<a>` can show and hide an element if they each reference it with their `href` or `data-target` attribute
+
+{% example html %}
+<p>
+ <a class="btn btn-primary" data-toggle="collapse" href="#multiCollapseExample1" aria-expanded="false" aria-controls="multiCollapseExample1">Toggle first element</a>
+ <button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#multiCollapseExample2" aria-expanded="false" aria-controls="multiCollapseExample1">Toggle second element</button>
+ <button class="btn btn-primary" type="button" data-toggle="collapse" data-target=".multi-collapse" aria-expanded="false" aria-controls="multiCollapseExample1 multiCollapseExample2">Toggle both elements</button>
+</p>
+<div class="row">
+ <div class="col">
+ <div class="collapse multi-collapse" id="multiCollapseExample1">
+ <div class="card card-block">
+ Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident.
+ </div>
+ </div>
+ </div>
+ <div class="col">
+ <div class="collapse multi-collapse" id="multiCollapseExample2">
+ <div class="card card-block">
+ Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident.
+ </div>
+ </div>
+ </div>
+</div>
+{% endexample %}
+
## Accordion example
Using the [card]({{ site.baseurl }}/docs/{{ site.docs_version }}/components/card/) component, you can extend the default collapse behavior to create an accordion.
@@ -129,7 +158,7 @@ These classes can be found in `_transitions.scss`.
### Via data attributes
-Just add `data-toggle="collapse"` and a `data-target` to the element to automatically assign control of a collapsible element. The `data-target` attribute accepts a CSS selector to apply the collapse to. Be sure to add the class `collapse` to the collapsible element. If you'd like it to default open, add the additional class `show`.
+Just add `data-toggle="collapse"` and a `data-target` to the element to automatically assign control of one or more collapsible elements. The `data-target` attribute accepts a CSS selector to apply the collapse to. Be sure to add the class `collapse` to the collapsible element. If you'd like it to default open, add the additional class `show`.
To add accordion-like group management to a collapsible area, add the data attribute `data-parent="#selector"`. Refer to the demo to see this in action.
diff --git a/docs/4.0/components/dropdowns.md b/docs/4.0/components/dropdowns.md
index 01c35c7a2..4840e8480 100644
--- a/docs/4.0/components/dropdowns.md
+++ b/docs/4.0/components/dropdowns.md
@@ -10,7 +10,7 @@ toc: true
Dropdowns are toggleable, contextual overlays for displaying lists of links and more. They're made interactive with the included Bootstrap dropdown JavaScript plugin. They're toggled by clicking, not by hovering; this is [an intentional design decision.](http://markdotto.com/2012/02/27/bootstrap-explained-dropdowns/)
-Dropdowns are built on a third party library, [Popper.js](https://popper.js.org), which provides dynamic positioning and viewport detection. Be sure to include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js) before Bootstrap's JavaScript.
+Dropdowns are built on a third party library, [Popper.js](https://popper.js.org), which provides dynamic positioning and viewport detection. Be sure to include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.10.1/umd/popper.min.js) before Bootstrap's JavaScript.
## Accessibility
diff --git a/docs/4.0/components/forms.md b/docs/4.0/components/forms.md
index 87f47a7ba..0a5756c4d 100644
--- a/docs/4.0/components/forms.md
+++ b/docs/4.0/components/forms.md
@@ -6,11 +6,13 @@ group: components
toc: true
---
-## Form controls
+## Overview
+
+Bootstrap's form controls expand on [our Rebooted form styles]({{ site.baseurl }}/docs/{{ site.docs_version }}/content/reboot/#forms) with classes. Use these classes to opt into their customized displays for a more consistent rendering across browsers and devices.
-Bootstrap's form controls expand on [our Rebooted form styles]({{ site.baseurl }}/docs/{{ site.docs_version }}/content/reboot/#forms) with classes. Use these classes to opt into their customized displays for a more consistent rendering across browsers and devices. The example form below demonstrates common HTML form elements that receive updated styles from Bootstrap with additional classes.
+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.
-Remember, since Bootstrap utilizes the HTML5 doctype, **all inputs must have a `type` attribute**.
+Here's a quick example to demonstrate Bootstrap's form styles. Keep reading for documentation on required classes, form layout, and more.
{% example html %}
<form>
@@ -23,9 +25,31 @@ Remember, since Bootstrap utilizes the HTML5 doctype, **all inputs must have a `
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
+ <div class="form-check">
+ <label class="form-check-label">
+ <input type="checkbox" class="form-check-input">
+ Check me out
+ </label>
+ </div>
+ <button type="submit" class="btn btn-primary">Submit</button>
+</form>
+{% endexample %}
+
+## Form controls
+
+Textual form controls—like `<input>`s, `<select>`s, and `<textarea>`s—are styled with the `.form-control` class. Included are styles for general appearance, focus state, sizing, and more.
+
+Be sure to explore our [custom forms](#custom-forms) to further style `<select>`s.
+
+{% example html %}
+<form>
+ <div class="form-group">
+ <label for="exampleFormControlInput1">Email address</label>
+ <input type="email" class="form-control" id="exampleFormControlInput1" placeholder="[email protected]">
+ </div>
<div class="form-group">
- <label for="exampleSelect1">Example select</label>
- <select class="form-control" id="exampleSelect1">
+ <label for="exampleFormControlSelect1">Example select</label>
+ <select class="form-control" id="exampleFormControlSelect1">
<option>1</option>
<option>2</option>
<option>3</option>
@@ -34,8 +58,8 @@ Remember, since Bootstrap utilizes the HTML5 doctype, **all inputs must have a `
</select>
</div>
<div class="form-group">
- <label for="exampleSelect2">Example multiple select</label>
- <select multiple class="form-control" id="exampleSelect2">
+ <label for="exampleFormControlSelect2">Example multiple select</label>
+ <select multiple class="form-control" id="exampleFormControlSelect2">
<option>1</option>
<option>2</option>
<option>3</option>
@@ -44,207 +68,192 @@ Remember, since Bootstrap utilizes the HTML5 doctype, **all inputs must have a `
</select>
</div>
<div class="form-group">
- <label for="exampleTextarea">Example textarea</label>
- <textarea class="form-control" id="exampleTextarea" rows="3"></textarea>
+ <label for="exampleFormControlTextarea1">Example textarea</label>
+ <textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
</div>
+</form>
+{% endexample %}
+
+For file inputs, swap the `.form-control` for `.form-control-file`.
+
+{% example html %}
+<form>
<div class="form-group">
- <label for="exampleInputFile">File input</label>
- <input type="file" class="form-control-file" id="exampleInputFile" aria-describedby="fileHelp">
- <small id="fileHelp" class="form-text text-muted">This is some placeholder block-level help text for the above input. It's a bit lighter and easily wraps to a new line.</small>
+ <label for="exampleFormControlFile1">Example file input</label>
+ <input type="file" class="form-control-file" id="exampleFormControlFile1">
</div>
- <fieldset class="form-group">
- <legend>Radio buttons</legend>
- <div class="form-check">
- <label class="form-check-label">
- <input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios1" value="option1" checked>
- Option one is this and that&mdash;be sure to include why it's great
- </label>
- </div>
- <div class="form-check">
- <label class="form-check-label">
- <input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios2" value="option2">
- Option two can be something else and selecting it will deselect option one
- </label>
+</form>
+{% endexample %}
+
+### Sizing
+
+Set heights using classes like `.form-control-lg` and `.form-control-sm`.
+
+{% example html %}
+<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">
+{% endexample %}
+
+{% example html %}
+<select class="form-control form-control-lg">
+ <option>Large select</option>
+</select>
+<select class="form-control">
+ <option>Default select</option>
+</select>
+<select class="form-control form-control-sm">
+ <option>Small select</option>
+</select>
+{% endexample %}
+
+### 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 html %}
+<input class="form-control" type="text" placeholder="Readonly input here…" readonly>
+{% endexample %}
+
+### 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 html %}
+<form>
+ <div class="form-group 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 protected]">
</div>
- <div class="form-check disabled">
- <label class="form-check-label">
- <input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios3" value="option3" disabled>
- Option three is disabled
- </label>
+ </div>
+ <div class="form-group 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" placeholder="Password">
</div>
- </fieldset>
- <div class="form-check">
- <label class="form-check-label">
- <input type="checkbox" class="form-check-input">
- Check me out
- </label>
</div>
- <button type="submit" class="btn btn-primary">Submit</button>
</form>
{% endexample %}
-Below is a complete list of the specific form controls supported by Bootstrap and the classes that customize them. Additional documentation is available for each group.
-
-<table>
- <thead>
- <tr>
- <th>Classes</th>
- <th>Used for</th>
- <th>Supported variations</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>
- {% markdown %}`.form-group`{% endmarkdown %}
- </td>
- <td class="text-nowrap">
- Any group of form controls
- </td>
- <td>
- {% markdown %}Use with any block-level element like `<fieldset>` or `<div>`{% endmarkdown %}
- </td>
- </tr>
- <tr>
- <td rowspan="3">
- {% markdown %}`.form-control`{% endmarkdown %}
- </td>
- <td>
- Textual inputs
- </td>
- <td>
- {% markdown %}`text`, `password`, `datetime-local`, `date`, `month`, `time`, `week`, `number`, `email`, `url`, `search`, `tel`, `color`{% endmarkdown %}
- </td>
- </tr>
- <tr>
- <td>
- Select menus
- </td>
- <td>
- {% markdown %}`multiple`, `size`{% endmarkdown %}
- </td>
- </tr>
- <tr>
- <td>
- Textareas
- </td>
- <td>
- <span class="text-muted">N/A</span>
- </td>
- </tr>
- <tr>
- <td class="text-nowrap">
- {% markdown %}`.form-control-file`{% endmarkdown %}
- </td>
- <td>
- File inputs
- </td>
- <td>
- {% markdown %}`file`{% endmarkdown %}
- </td>
- </tr>
- <tr>
- <td class="text-nowrap">
-{% markdown %}
-`.form-check`
-{% endmarkdown %}
- </td>
- <td class="text-nowrap">
- Checkboxes and radios
- </td>
- <td>
- <span class="text-muted">N/A</span>
- </td>
- </tr>
- </tbody>
-</table>
-
-### Textual inputs
-
-Here are examples of `.form-control` applied to each textual HTML5 `<input>` `type`.
-
-{% example html %}
-<div class="form-group row">
- <label for="example-text-input" class="col-2 col-form-label">Text</label>
- <div class="col-10">
- <input class="form-control" type="text" value="Artisanal kale" id="example-text-input">
+{% example html %}
+<form class="form-inline">
+ <div class="form-group">
+ <label for="staticEmail2" class="sr-only">Email</label>
+ <input type="text" readonly class="form-control-plaintext" id="staticEmail2" value="[email protected]">
</div>
-</div>
-<div class="form-group row">
- <label for="example-search-input" class="col-2 col-form-label">Search</label>
- <div class="col-10">
- <input class="form-control" type="search" value="How do I shoot web" id="example-search-input">
+ <div class="form-group mx-sm-3">
+ <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">Confirm identity</button>
+</form>
+{% endexample %}
+
+## Checkboxes and radios
+
+Default checkboxes and radios are improved upon with the help of `.form-check`, **a single class for both input types that improves the layout and behavior of their HTML elements**. Checkboxes are for selecting one or several options in a list, while radios are for selecting one option from many.
+
+Disabled checkboxes and radios are supported, but to provide a `not-allowed` cursor on hover of the parent `<label>`, you'll need to add the `.disabled` class to the parent `.form-check`. The disabled class will also lighten the text color to help indicate the input's state.
+
+### 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 html %}
+<div class="form-check">
+ <label class="form-check-label">
+ <input class="form-check-input" type="checkbox" value="">
+ Option one is this and that&mdash;be sure to include why it's great
+ </label>
</div>
-<div class="form-group row">
- <label for="example-email-input" class="col-2 col-form-label">Email</label>
- <div class="col-10">
- <input class="form-control" type="email" value="[email protected]" id="example-email-input">
- </div>
+<div class="form-check disabled">
+ <label class="form-check-label">
+ <input class="form-check-input" type="checkbox" value="" disabled>
+ Option two is disabled
+ </label>
</div>
-<div class="form-group row">
- <label for="example-url-input" class="col-2 col-form-label">URL</label>
- <div class="col-10">
- <input class="form-control" type="url" value="https://getbootstrap.com" id="example-url-input">
- </div>
+{% endexample %}
+
+{% example html %}
+<div class="form-check">
+ <label class="form-check-label">
+ <input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios1" value="option1" checked>
+ Option one is this and that&mdash;be sure to include why it's great
+ </label>
</div>
-<div class="form-group row">
- <label for="example-tel-input" class="col-2 col-form-label">Telephone</label>
- <div class="col-10">
- <input class="form-control" type="tel" value="1-(555)-555-5555" id="example-tel-input">
- </div>
+<div class="form-check">
+ <label class="form-check-label">
+ <input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios2" value="option2">
+ Option two can be something else and selecting it will deselect option one
+ </label>
</div>
-<div class="form-group row">
- <label for="example-password-input" class="col-2 col-form-label">Password</label>
- <div class="col-10">
- <input class="form-control" type="password" value="hunter2" id="example-password-input">
- </div>
+<div class="form-check disabled">
+ <label class="form-check-label">
+ <input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios3" value="option3" disabled>
+ Option three is disabled
+ </label>
</div>
-<div class="form-group row">
- <label for="example-number-input" class="col-2 col-form-label">Number</label>
- <div class="col-10">
- <input class="form-control" type="number" value="42" id="example-number-input">
- </div>
+{% endexample %}
+
+### Inline
+
+Group checkboxes or radios on the same horizontal row by adding `.form-check-inline` to any `.form-check`.
+
+{% example html %}
+<div class="form-check form-check-inline">
+ <label class="form-check-label">
+ <input class="form-check-input" type="checkbox" id="inlineCheckbox1" value="option1"> 1
+ </label>
</div>
-<div class="form-group row">
- <label for="example-datetime-local-input" class="col-2 col-form-label">Date and time</label>
- <div class="col-10">
- <input class="form-control" type="datetime-local" value="2011-08-19T13:45:00" id="example-datetime-local-input">
- </div>
+<div class="form-check form-check-inline">
+ <label class="form-check-label">
+ <input class="form-check-input" type="checkbox" id="inlineCheckbox2" value="option2"> 2
+ </label>
</div>
-<div class="form-group row">
- <label for="example-date-input" class="col-2 col-form-label">Date</label>
- <div class="col-10">
- <input class="form-control" type="date" value="2011-08-19" id="example-date-input">
- </div>
+<div class="form-check form-check-inline disabled">
+ <label class="form-check-label">
+ <input class="form-check-input" type="checkbox" id="inlineCheckbox3" value="option3" disabled> 3
+ </label>
</div>
-<div class="form-group row">
- <label for="example-month-input" class="col-2 col-form-label">Month</label>
- <div class="col-10">
- <input class="form-control" type="month" value="2011-08" id="example-month-input">
- </div>
+{% endexample %}
+
+{% example html %}
+<div class="form-check form-check-inline">
+ <label class="form-check-label">
+ <input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio1" value="option1"> 1
+ </label>
</div>
-<div class="form-group row">
- <label for="example-week-input" class="col-2 col-form-label">Week</label>
- <div class="col-10">
- <input class="form-control" type="week" value="2011-W33" id="example-week-input">
- </div>
+<div class="form-check form-check-inline">
+ <label class="form-check-label">
+ <input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio2" value="option2"> 2
+ </label>
</div>
-<div class="form-group row">
- <label for="example-time-input" class="col-2 col-form-label">Time</label>
- <div class="col-10">
- <input class="form-control" type="time" value="13:45:00" id="example-time-input">
- </div>
+<div class="form-check form-check-inline disabled">
+ <label class="form-check-label">
+ <input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio3" value="option3" disabled> 3
+ </label>
</div>
-<div class="form-group row">
- <label for="example-color-input" class="col-2 col-form-label">Color</label>
- <div class="col-10">
- <input class="form-control" type="color" value="#563d7c" id="example-color-input">
- </div>
+{% endexample %}
+
+### Without labels
+
+Should you have no text within the `<label>`, the input is positioned as you'd expect. **Currently only works on non-inline checkboxes and radios.** Remember to still provide some form of label for assistive technologies (for instance, using `aria-label`).
+
+{% example html %}
+<div class="form-check">
+ <label class="form-check-label">
+ <input class="form-check-input" type="checkbox" id="blankCheckbox" value="option1" aria-label="...">
+ </label>
+</div>
+<div class="form-check">
+ <label class="form-check-label">
+ <input class="form-check-input" type="radio" name="blankRadio" id="blankRadio1" value="option1" aria-label="...">
+ </label>
</div>
{% endexample %}
-## Form layouts
+## Layout
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.
@@ -265,67 +274,90 @@ The `.form-group` class is the easiest way to add some structure to forms. Its o
</form>
{% endexample %}
-### 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.
+### Form grid
-- Controls are `display: flex`, collapsing any HTML white space and allowing you to provide alignment control with [spacing]({{ site.baseurl }}/docs/{{ site.docs_version }}/utilities/spacing/) and [flexbox]({{ site.baseurl }}/docs/{{ site.docs_version }}/utilities/flexbox/) 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]({{ site.baseurl }}/docs/{{ site.docs_version }}/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`.
+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.
{% example html %}
-<form class="form-inline">
- <label class="sr-only" for="inlineFormInput">Name</label>
- <input type="text" class="form-control mb-2 mr-sm-2 mb-sm-0" id="inlineFormInput" placeholder="Jane Doe">
-
- <label class="sr-only" for="inlineFormInputGroup">Username</label>
- <div class="input-group mb-2 mr-sm-2 mb-sm-0">
- <div class="input-group-addon">@</div>
- <input type="text" class="form-control" id="inlineFormInputGroup" placeholder="Username">
- </div>
-
- <div class="form-check mb-2 mr-sm-2 mb-sm-0">
- <label class="form-check-label">
- <input class="form-check-input" type="checkbox"> Remember me
- </label>
+<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>
-
- <button type="submit" class="btn btn-primary">Submit</button>
</form>
{% endexample %}
-Custom form controls and selects are also supported.
+#### 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.
{% example html %}
-<form class="form-inline">
- <label class="mr-sm-2" for="inlineFormCustomSelect">Preference</label>
- <select class="custom-select mb-2 mr-sm-2 mb-sm-0" id="inlineFormCustomSelect">
- <option selected>Choose...</option>
- <option value="1">One</option>
- <option value="2">Two</option>
- <option value="3">Three</option>
- </select>
+<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>
+{% endexample %}
- <label class="custom-control custom-checkbox mb-2 mr-sm-2 mb-sm-0">
- <input type="checkbox" class="custom-control-input">
- <span class="custom-control-indicator"></span>
- <span class="custom-control-description">Remember my preference</span>
- </label>
+More complex layouts can also be created with the grid system.
- <button type="submit" class="btn btn-primary">Submit</button>
+{% example html %}
+<form>
+ <div class="form-row">
+ <div class="form-group col-md-6">
+ <label for="inputEmail4" class="col-form-label">Email</label>
+ <input type="email" class="form-control" id="inputEmail4" placeholder="Email">
+ </div>
+ <div class="form-group col-md-6">
+ <label for="inputPassword4" class="col-form-label">Password</label>
+ <input type="password" class="form-control" id="inputPassword4" placeholder="Password">
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="inputAddress" class="col-form-label">Address</label>
+ <input type="text" class="form-control" id="inputAddress" placeholder="1234 Main St">
+ </div>
+ <div class="form-group">
+ <label for="inputAddress2" class="col-form-label">Address 2</label>
+ <input type="text" class="form-control" id="inputAddress2" placeholder="Apartment, studio, or floor">
+ </div>
+ <div class="form-row">
+ <div class="form-group col-md-6">
+ <label for="inputCity" class="col-form-label">City</label>
+ <input type="text" class="form-control" id="inputCity">
+ </div>
+ <div class="form-group col-md-4">
+ <label for="inputState" class="col-form-label">State</label>
+ <select id="inputState" class="form-control">Choose</select>
+ </div>
+ <div class="form-group col-md-2">
+ <label for="inputZip" class="col-form-label">Zip</label>
+ <input type="text" class="form-control" id="inputZip">
+ </div>
+ </div>
+ <div class="form-group">
+ <div class="form-check">
+ <label class="form-check-label">
+ <input class="form-check-input" type="checkbox"> Check me out
+ </label>
+ </div>
+ </div>
+ <button type="submit" class="btn btn-primary">Sign in</button>
</form>
{% endexample %}
-{% 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.
-{% endcallout %}
-
-### Using the Grid
+#### Horizontal form
-For more structured form layouts that are also responsive, you can utilize Bootstrap's [predefined grid classes]({{ site.baseurl }}/docs/{{ site.docs_version }}/layout/grid/) or [mixins]({{ site.baseurl }}/docs/{{ site.docs_version }}/layout/grid/#sass-mixins) to create horizontal forms. Add the `.row` class to form groups and use the `.col-*-*` classes to specify the width of your labels and controls.
+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. For `<legend>` elements, you can use `.col-form-legend` to make them appear similar to regular `<label>` elements.
@@ -388,215 +420,209 @@ Be sure to add `.col-form-label` to your `<label>`s as well so they're verticall
</div>
{% endexample %}
-More complex layouts can also be created with the grid system.
+#### 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 html %}
-<div class="container">
- <form>
- <div class="row">
- <div class="form-group col-md-6">
- <label for="inputEmail4" class="col-form-label">Email</label>
- <input type="email" class="form-control" id="inputEmail4" placeholder="Email">
- </div>
- <div class="form-group col-md-6">
- <label for="inputPassword4" class="col-form-label">Password</label>
- <input type="password" class="form-control" id="inputPassword4" placeholder="Password">
- </div>
+<form>
+ <div class="form-row">
+ <div class="col-7">
+ <input type="text" class="form-control" placeholder="City">
</div>
- <div class="form-group">
- <label for="inputAddress" class="col-form-label">Address</label>
- <input type="text" class="form-control" id="inputAddress" placeholder="1234 Main St">
+ <div class="col">
+ <input type="text" class="form-control" placeholder="State">
</div>
- <div class="form-group">
- <label for="inputAddress2" class="col-form-label">Address 2</label>
- <input type="text" class="form-control" id="inputAddress2" placeholder="Apartment, studio, or floor">
+ <div class="col">
+ <input type="text" class="form-control" placeholder="Zip">
</div>
- <div class="row">
- <div class="form-group col-md-6">
- <label for="inputCity" class="col-form-label">City</label>
- <input type="text" class="form-control" id="inputCity">
- </div>
- <div class="form-group col-md-4">
- <label for="inputState" class="col-form-label">State</label>
- <select id="inputState" class="form-control">Choose</select>
- </div>
- <div class="form-group col-md-2">
- <label for="inputZip" class="col-form-label">Zip</label>
- <input type="text" class="form-control" id="inputZip">
+ </div>
+</form>
+{% endexample html %}
+
+#### 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 html %}
+<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 mb-sm-0" id="inlineFormInput" placeholder="Jane Doe">
+ </div>
+ <div class="col-auto">
+ <label class="sr-only" for="inlineFormInputGroup">Username</label>
+ <div class="input-group mb-2 mb-sm-0">
+ <div class="input-group-addon">@</div>
+ <input type="text" class="form-control" id="inlineFormInputGroup" placeholder="Username">
</div>
</div>
- <div class="form-group">
- <div class="form-check">
+ <div class="col-auto">
+ <div class="form-check mb-2 mb-sm-0">
<label class="form-check-label">
- <input class="form-check-input" type="checkbox"> Check me out
+ <input class="form-check-input" type="checkbox"> Remember me
</label>
</div>
</div>
- <button type="submit" class="btn btn-primary">Sign in</button>
- </form>
-</div>
+ <div class="col-auto">
+ <button type="submit" class="btn btn-primary">Submit</button>
+ </div>
+ </div>
+</form>
{% endexample %}
-Grid-based form layouts also support large and small inputs.
+You can then remix that once again with size-specific column classes.
{% example html %}
-<div class="container">
- <form>
- <div class="form-group row">
- <label for="lgFormGroupInput" 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="lgFormGroupInput" placeholder="[email protected]">
+<form>
+ <div class="form-row align-items-center">
+ <div class="col-sm-3">
+ <label class="sr-only" for="inlineFormInput">Name</label>
+ <input type="text" class="form-control mb-2 mb-sm-0" id="inlineFormInput" placeholder="Jane Doe">
+ </div>
+ <div class="col-sm-3">
+ <label class="sr-only" for="inlineFormInputGroup">Username</label>
+ <div class="input-group mb-2 mb-sm-0">
+ <div class="input-group-addon">@</div>
+ <input type="text" class="form-control" id="inlineFormInputGroup" placeholder="Username">
</div>
</div>
- <div class="form-group row">
- <label for="smFormGroupInput" 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="smFormGroupInput" placeholder="[email protected]">
+ <div class="col-auto">
+ <div class="form-check mb-2 mb-sm-0">
+ <label class="form-check-label">
+ <input class="form-check-input" type="checkbox"> Remember me
+ </label>
</div>
</div>
- </form>
-</div>
+ <div class="col-auto">
+ <button type="submit" class="btn btn-primary">Submit</button>
+ </div>
+ </div>
+</form>
{% endexample %}
-## Checkboxes and radios
+And of course [custom form controls](#custom-forms) are supported.
-Default checkboxes and radios are improved upon with the help of `.form-check`, **a single class for both input types that improves the layout and behavior of their HTML elements**. Checkboxes are for selecting one or several options in a list, while radios are for selecting one option from many.
+{% example html %}
+<form>
+ <div class="form-row align-items-center">
+ <div class="col-auto">
+ <label class="mr-sm-2" for="inlineFormCustomSelect">Preference</label>
+ <select class="custom-select mb-2 mr-sm-2 mb-sm-0" id="inlineFormCustomSelect">
+ <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">
+ <label class="custom-control custom-checkbox mb-2 mr-sm-2 mb-sm-0">
+ <input type="checkbox" class="custom-control-input">
+ <span class="custom-control-indicator"></span>
+ <span class="custom-control-description">Remember my preference</span>
+ </label>
+ </div>
+ <div class="col-auto">
+ <button type="submit" class="btn btn-primary">Submit</button>
+ </div>
+ </div>
+</form>
+{% endexample %}
-Disabled checkboxes and radios are supported, but to provide a `not-allowed` cursor on hover of the parent `<label>`, you'll need to add the `.disabled` class to the parent `.form-check`. The disabled class will also lighten the text color to help indicate the input's state.
+### Inline forms
-### Default (stacked)
+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.
-By default, any number of checkboxes and radios that are immediate sibling will be vertically stacked and appropriately spaced with `.form-check`.
+- Controls are `display: flex`, collapsing any HTML white space and allowing you to provide alignment control with [spacing]({{ site.baseurl }}/docs/{{ site.docs_version }}/utilities/spacing/) and [flexbox]({{ site.baseurl }}/docs/{{ site.docs_version }}/utilities/flexbox/) 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.
-{% example html %}
-<div class="form-check">
- <label class="form-check-label">
- <input class="form-check-input" type="checkbox" value="">
- Option one is this and that&mdash;be sure to include why it's great
- </label>
-</div>
-<div class="form-check disabled">
- <label class="form-check-label">
- <input class="form-check-input" type="checkbox" value="" disabled>
- Option two is disabled
- </label>
-</div>
-{% endexample %}
+You may need to manually address the width and alignment of individual form controls with [spacing utilities]({{ site.baseurl }}/docs/{{ site.docs_version }}/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 html %}
-<div class="form-check">
- <label class="form-check-label">
- <input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios1" value="option1" checked>
- Option one is this and that&mdash;be sure to include why it's great
- </label>
-</div>
-<div class="form-check">
- <label class="form-check-label">
- <input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios2" value="option2">
- Option two can be something else and selecting it will deselect option one
- </label>
-</div>
-<div class="form-check disabled">
- <label class="form-check-label">
- <input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios3" value="option3" disabled>
- Option three is disabled
- </label>
-</div>
-{% endexample %}
+<form class="form-inline">
+ <label class="sr-only" for="inlineFormInput">Name</label>
+ <input type="text" class="form-control mb-2 mr-sm-2 mb-sm-0" id="inlineFormInput" placeholder="Jane Doe">
-### Inline
+ <label class="sr-only" for="inlineFormInputGroup">Username</label>
+ <div class="input-group mb-2 mr-sm-2 mb-sm-0">
+ <div class="input-group-addon">@</div>
+ <input type="text" class="form-control" id="inlineFormInputGroup" placeholder="Username">
+ </div>
-Group checkboxes or radios on the same horizontal row by adding `.form-check-inline` to any `.form-check`.
+ <div class="form-check mb-2 mr-sm-2 mb-sm-0">
+ <label class="form-check-label">
+ <input class="form-check-input" type="checkbox"> Remember me
+ </label>
+ </div>
-{% example html %}
-<div class="form-check form-check-inline">
- <label class="form-check-label">
- <input class="form-check-input" type="checkbox" id="inlineCheckbox1" value="option1"> 1
- </label>
-</div>
-<div class="form-check form-check-inline">
- <label class="form-check-label">
- <input class="form-check-input" type="checkbox" id="inlineCheckbox2" value="option2"> 2
- </label>
-</div>
-<div class="form-check form-check-inline disabled">
- <label class="form-check-label">
- <input class="form-check-input" type="checkbox" id="inlineCheckbox3" value="option3" disabled> 3
- </label>
-</div>
+ <button type="submit" class="btn btn-primary">Submit</button>
+</form>
{% endexample %}
+Custom form controls and selects are also supported.
+
{% example html %}
-<div class="form-check form-check-inline">
- <label class="form-check-label">
- <input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio1" value="option1"> 1
- </label>
-</div>
-<div class="form-check form-check-inline">
- <label class="form-check-label">
- <input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio2" value="option2"> 2
- </label>
-</div>
-<div class="form-check form-check-inline disabled">
- <label class="form-check-label">
- <input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio3" value="option3" disabled> 3
+<form class="form-inline">
+ <label class="mr-sm-2" for="inlineFormCustomSelect">Preference</label>
+ <select class="custom-select mb-2 mr-sm-2 mb-sm-0" id="inlineFormCustomSelect">
+ <option selected>Choose...</option>
+ <option value="1">One</option>
+ <option value="2">Two</option>
+ <option value="3">Three</option>
+ </select>
+
+ <label class="custom-control custom-checkbox mb-2 mr-sm-2 mb-sm-0">
+ <input type="checkbox" class="custom-control-input">
+ <span class="custom-control-indicator"></span>
+ <span class="custom-control-description">Remember my preference</span>
</label>
-</div>
+
+ <button type="submit" class="btn btn-primary">Submit</button>
+</form>
{% endexample %}
-### Without labels
+{% 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.
+{% endcallout %}
-Should you have no text within the `<label>`, the input is positioned as you'd expect. **Currently only works on non-inline checkboxes and radios.** Remember to still provide some form of label for assistive technologies (for instance, using `aria-label`).
+## Help text
-{% example html %}
-<div class="form-check">
- <label class="form-check-label">
- <input class="form-check-input" type="checkbox" id="blankCheckbox" value="option1" aria-label="...">
- </label>
-</div>
-<div class="form-check">
- <label class="form-check-label">
- <input class="form-check-input" type="radio" name="blankRadio" id="blankRadio1" value="option1" aria-label="...">
- </label>
-</div>
-{% endexample %}
+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`.
-## Static controls
+{% callout warning %}
+##### Associating help text with form controls
-If you want to have read-only fields in your form styled as plain text, use the `.form-control-static` class to remove the default form field styling and preserve the correct margin and padding.
+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.
+{% endcallout %}
+
+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 html %}
-<form>
- <div class="form-group 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-static" id="staticEmail" value="[email protected]">
- </div>
- </div>
- <div class="form-group 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" placeholder="Password">
- </div>
- </div>
-</form>
+<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>
{% endexample %}
+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 html %}
<form class="form-inline">
<div class="form-group">
- <label for="staticEmail2" class="sr-only">Email</label>
- <input type="text" readonly class="form-control-static" id="staticEmail2" value="[email protected]">
- </div>
- <div class="form-group mx-sm-3">
- <label for="inputPassword2" class="sr-only">Password</label>
- <input type="password" class="form-control" id="inputPassword2" placeholder="Password">
+ <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>
- <button type="submit" class="btn btn-primary">Confirm identity</button>
</form>
{% endexample %}
-## Disabled states
+## Disabled forms
Add the `disabled` boolean attribute on an input to prevent user interactions and make it appear lighter.
@@ -641,203 +667,217 @@ By default, browsers will treat all native form controls (`<input>`, `<select>`
While Bootstrap will apply these styles in all browsers, Internet Explorer 11 and below don't fully support the `disabled` attribute on a `<fieldset>`. Use custom JavaScript to disable the fieldset in these browsers.
{% endcallout %}
-## Readonly inputs
+## Validation
-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.
+Provide valuable, actionable feedback to your users with HTML5 form validation–[available in all our supported browsers](http://caniuse.com/#feat=form-validation). Choose from the browser default validation feedback, or implement custom messages with our built-in classes and starter JavaScript.
-{% example html %}
-<input class="form-control" type="text" placeholder="Readonly input here…" readonly>
-{% endexample %}
+{% callout warning %}
+We **highly recommend** custom validation styles as native browser defaults are not announced to screen readers.
+{% endcallout %}
-## Control sizing
+### How it works
-Set heights using classes like `.form-control-lg`, and set widths using grid column classes like `.col-lg-*`.
+Here's how form validation works with Bootstrap:
-{% example html %}
-<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">
-{% endexample %}
+- 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).
+- 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 constaints 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/forms.html#the-constraint-validation-api), a series of JavaScript methods for validating form controls.
+- Feedback messages may utilize the [browser defaults](#browser-default) (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.
-{% example html %}
-<select class="form-control form-control-lg">
- <option>Large select</option>
-</select>
-<select class="form-control">
- <option>Default select</option>
-</select>
-<select class="form-control form-control-sm">
- <option>Small select</option>
-</select>
-{% endexample %}
+With that in mind, consider the following demos for our custom form validation styles, optional server side classes, and browser defaults.
+
+### Custom styles
-## Column sizing
+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.
-Wrap inputs in grid columns, or any custom parent element, to easily enforce desired widths.
+When attempting to submit, you'll see the `:invalid` and `:valid` styles applied to your form controls.
{% example html %}
-<div class="row">
- <div class="col-2">
- <input type="text" class="form-control" placeholder=".col-2">
- </div>
- <div class="col-3">
- <input type="text" class="form-control" placeholder=".col-3">
+<form class="container" id="needs-validation" novalidate>
+ <div class="row">
+ <div class="col-md-6 mb-3">
+ <label for="validationCustom01">First name</label>
+ <input type="text" class="form-control" id="validationCustom01" placeholder="First name" value="Mark" required>
+ </div>
+ <div class="col-md-6 mb-3">
+ <label for="validationCustom02">Last name</label>
+ <input type="text" class="form-control" id="validationCustom02" placeholder="Last name" value="Otto" required>
+ </div>
</div>
- <div class="col-4">
- <input type="text" class="form-control" placeholder=".col-4">
+ <div class="row">
+ <div class="col-md-6 mb-3">
+ <label for="validationCustom03">City</label>
+ <input type="text" class="form-control" id="validationCustom03" placeholder="City" required>
+ <div class="invalid-feedback">
+ Please provide a valid city.
+ </div>
+ </div>
+ <div class="col-md-3 mb-3">
+ <label for="validationCustom04">State</label>
+ <input type="text" class="form-control" id="validationCustom04" placeholder="State" required>
+ <div class="invalid-feedback">
+ Please provide 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" placeholder="Zip" required>
+ <div class="invalid-feedback">
+ Please provide a valid zip.
+ </div>
+ </div>
</div>
-</div>
-{% endexample %}
-
-## 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.
-{% endcallout %}
-
-### Block level
-
-Block help text—for below inputs or for longer lines of help text—can be easily achieved with `.form-text`. This class includes `display: block` and adds some top margin for easy spacing from the inputs above.
+ <button class="btn btn-primary" type="submit">Submit form</button>
+</form>
-{% example html %}
-<label for="inputPassword5">Password</label>
-<input type="password" id="inputPassword5" class="form-control" aria-describedby="passwordHelpBlock">
-<p 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.
-</p>
+<script>
+// Example starter JavaScript for disabling form submissions if there are invalid fields
+(function() {
+ "use strict";
+ window.addEventListener("load", function() {
+ var form = document.getElementById("needs-validation");
+ form.addEventListener("submit", function(event) {
+ if (form.checkValidity() == false) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ form.classList.add("was-validated");
+ }, false);
+ }, false);
+}());
+</script>
{% endexample %}
-### Inline
+### 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.
-Inline text can use any typical inline HTML element (be it a `<small>`, `<span>`, or something else).
+While these feedback styles cannot be styled with CSS, you can still customize the feedback text through JavaScript.
{% example html %}
-<form class="form-inline">
- <div class="form-group">
- <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>
+<form>
+ <div class="row">
+ <div class="col-md-6 mb-3">
+ <label for="validationDefault01">First name</label>
+ <input type="text" class="form-control" id="validationDefault01" placeholder="First name" value="Mark" required>
+ </div>
+ <div class="col-md-6 mb-3">
+ <label for="validationDefault02">Last name</label>
+ <input type="text" class="form-control" id="validationDefault02" placeholder="Last name" value="Otto" required>
+ </div>
</div>
+ <div class="row">
+ <div class="col-md-6 mb-3">
+ <label for="validationDefault03">City</label>
+ <input type="text" class="form-control" id="validationDefault03" placeholder="City" required>
+ <div class="invalid-feedback">
+ Please provide a valid city.
+ </div>
+ </div>
+ <div class="col-md-3 mb-3">
+ <label for="validationDefault04">State</label>
+ <input type="text" class="form-control" id="validationDefault04" placeholder="State" required>
+ <div class="invalid-feedback">
+ Please provide a valid state.
+ </div>
+ </div>
+ <div class="col-md-3 mb-3">
+ <label for="validationDefault05">Zip</label>
+ <input type="text" class="form-control" id="validationDefault05" placeholder="Zip" required>
+ <div class="invalid-feedback">
+ Please provide a valid zip.
+ </div>
+ </div>
+ </div>
+
+ <button class="btn btn-primary" type="submit">Submit form</button>
</form>
{% endexample %}
-## Validation
-
-Bootstrap includes validation styles for danger, warning, and success states on most form controls.
-
-### How it works
-
-Here's a rundown of how they work:
-
-- To use, add `.has-warning`, `.has-danger`, or `.has-success` to the parent element. Any `.col-form-label`, `.form-control`, or custom form element will receive the validation styles.
-- Contextual validation text, in addition to your usual form field help text, can be added with the use of `.form-control-feedback`. This text will adapt to the parent `.has-*` class. By default it only includes a bit of `margin` for spacing and a modified `color` for each state.
-- Validation icons are `url()`s configured via Sass variables that are applied to `background-image` declarations for each state.
-- You may use your own base64 PNGs or SVGs by updating the Sass variables and recompiling.
-- Icons can also be disabled entirely by setting the variables to `none` or commenting out the source Sass.
-
-### Defining states
-
-Generally speaking, you'll want to use a particular state for specific types of feedback:
-
-- **Danger** is great for when there's a blocking or required field. A user *must* fill in this field properly to submit the form.
-- **Warning** works well for input values that are in progress, like password strength, or soft validation before a user attempts to submit a form.
-- And lastly, **success** is ideal for situations when you have per-field validation throughout a form and want to encourage a user through the rest of the fields.
-
-{% comment %}
-{% callout warning %}
-#### Conveying validation state to assistive technologies and colorblind users
-
-Using these validation styles to denote the state of a form control only provides a visual, color-based indication, which will not be conveyed to users of assistive technologies - such as screen readers - or to colorblind users.
-
-Ensure that an alternative indication of state is also provided. For instance, you can include a hint about state in the form control's `<label>` text itself (as is the case in the following code example), include a [Glyphicon]({{ site.baseurl }}/docs/{{ site.docs_version }}/components/#glyphicons) (with appropriate alternative text using the `.sr-only` class - see the [Glyphicon examples]({{ site.baseurl }}/docs/{{ site.docs_version }}/components/#glyphicons-examples)), or by providing an additional [help text](#forms-help-text) block. Specifically for assistive technologies, invalid form controls can also be assigned an `aria-invalid="true"` attribute.
-{% endcallout %}
-{% endcomment %}
-
-### Examples
-
-Here are some examples of the aforementioned classes in action. First up is your standard left-aligned fields with labels, help text, and validation messaging.
-
-{% example html %}
-<div class="form-group has-success">
- <label class="form-control-label" for="inputSuccess1">Input with success</label>
- <input type="text" class="form-control form-control-success" id="inputSuccess1">
- <div class="form-control-feedback">Success! You've done it.</div>
- <small class="form-text text-muted">Example help text that remains unchanged.</small>
-</div>
-<div class="form-group has-warning">
- <label class="form-control-label" for="inputWarning1">Input with warning</label>
- <input type="text" class="form-control form-control-warning" id="inputWarning1">
- <div class="form-control-feedback">Shucks, check the formatting of that and try again.</div>
- <small class="form-text text-muted">Example help text that remains unchanged.</small>
-</div>
-<div class="form-group has-danger">
- <label class="form-control-label" for="inputDanger1">Input with danger</label>
- <input type="text" class="form-control form-control-danger" id="inputDanger1">
- <div class="form-control-feedback">Sorry, that username's taken. Try another?</div>
- <small class="form-text text-muted">Example help text that remains unchanged.</small>
-</div>
-{% endexample %}
+### Server side
-Those same states can also be used with horizontal forms.
+We recommend using client side validation, but in case you require server side, 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 html %}
-<div class="container">
- <form>
- <div class="form-group row has-success">
- <label for="inputHorizontalSuccess" class="col-sm-2 col-form-label">Email</label>
- <div class="col-sm-10">
- <input type="email" class="form-control form-control-success" id="inputHorizontalSuccess" placeholder="[email protected]">
- <div class="form-control-feedback">Success! You've done it.</div>
- <small class="form-text text-muted">Example help text that remains unchanged.</small>
+<form>
+ <div class="row">
+ <div class="col-md-6 mb-3">
+ <label for="validationServer01">First name</label>
+ <input type="text" class="form-control is-valid" id="validationServer01" placeholder="First name" value="Mark" required>
+ </div>
+ <div class="col-md-6 mb-3">
+ <label for="validationServer02">Last name</label>
+ <input type="text" class="form-control is-valid" id="validationServer02" placeholder="Last name" value="Otto" required>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6 mb-3">
+ <label for="validationServer03">City</label>
+ <input type="text" class="form-control is-invalid" id="validationServer03" placeholder="City" required>
+ <div class="invalid-feedback">
+ Please provide a valid city.
</div>
</div>
- <div class="form-group row has-warning">
- <label for="inputHorizontalWarning" class="col-sm-2 col-form-label">Email</label>
- <div class="col-sm-10">
- <input type="email" class="form-control form-control-warning" id="inputHorizontalWarning" placeholder="[email protected]">
- <div class="form-control-feedback">Shucks, check the formatting of that and try again.</div>
- <small class="form-text text-muted">Example help text that remains unchanged.</small>
+ <div class="col-md-3 mb-3">
+ <label for="validationServer04">State</label>
+ <input type="text" class="form-control is-invalid" id="validationServer04" placeholder="State" required>
+ <div class="invalid-feedback">
+ Please provide a valid state.
</div>
</div>
- <div class="form-group row has-danger">
- <label for="inputHorizontalDnger" class="col-sm-2 col-form-label">Email</label>
- <div class="col-sm-10">
- <input type="email" class="form-control form-control-danger" id="inputHorizontalDnger" placeholder="[email protected]">
- <div class="form-control-feedback">Sorry, that username's taken. Try another?</div>
- <small class="form-text text-muted">Example help text that remains unchanged.</small>
+ <div class="col-md-3 mb-3">
+ <label for="validationServer05">Zip</label>
+ <input type="text" class="form-control is-invalid" id="validationServer05" placeholder="Zip" required>
+ <div class="invalid-feedback">
+ Please provide a valid zip.
</div>
</div>
- </form>
-</div>
+ </div>
+
+ <button class="btn btn-primary" type="submit">Submit form</button>
+</form>
{% endexample %}
-Checkboxes and radios are also supported.
+### Supported elements
+
+Our example forms show native textual `<input>`s above, but form validation styles are available for our custom form controls, too.
{% example html %}
-<div class="form-check has-success">
- <label class="form-check-label">
- <input type="checkbox" class="form-check-input" id="checkboxSuccess" value="option1">
- Checkbox with success
- </label>
-</div>
-<div class="form-check has-warning">
- <label class="form-check-label">
- <input type="checkbox" class="form-check-input" id="checkboxWarning" value="option1">
- Checkbox with warning
+<form class="was-validated">
+ <label class="custom-control custom-checkbox">
+ <input type="checkbox" class="custom-control-input" required>
+ <span class="custom-control-indicator"></span>
+ <span class="custom-control-description">Check this custom checkbox</span>
</label>
-</div>
-<div class="form-check has-danger">
- <label class="form-check-label">
- <input type="checkbox" class="form-check-input" id="checkboxDanger" value="option1">
- Checkbox with danger
+
+ <div class="custom-controls-stacked d-block my-3">
+ <label class="custom-control custom-radio">
+ <input id="radioStacked1" name="radio-stacked" type="radio" class="custom-control-input" required>
+ <span class="custom-control-indicator"></span>
+ <span class="custom-control-description">Toggle this custom radio</span>
+ </label>
+ <label class="custom-control custom-radio">
+ <input id="radioStacked2" name="radio-stacked" type="radio" class="custom-control-input" required>
+ <span class="custom-control-indicator"></span>
+ <span class="custom-control-description">Or toggle this other custom radio</span>
+ </label>
+ </div>
+
+ <select class="custom-select d-block my-3" required>
+ <option value="">Open this select menu</option>
+ <option value="1">One</option>
+ <option value="2">Two</option>
+ <option value="3">Three</option>
+ </select>
+
+ <label class="custom-file">
+ <input type="file" id="file" class="custom-file-input" required>
+ <span class="custom-file-control"></span>
</label>
-</div>
+</form>
{% endexample %}
## Custom forms
diff --git a/docs/4.0/components/popovers.md b/docs/4.0/components/popovers.md
index 20ab3fe75..cd6599158 100644
--- a/docs/4.0/components/popovers.md
+++ b/docs/4.0/components/popovers.md
@@ -11,7 +11,7 @@ toc: true
Things to know when using the popover plugin:
-- Popovers rely on the 3rd party library [Popper.js](https://popper.js.org) for positioning. You must include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js) before bootstrap.js in order for popovers to work!
+- Popovers rely on the 3rd party library [Popper.js](https://popper.js.org) for positioning. You must include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.10.1/umd/popper.min.js) before bootstrap.js in order for popovers to work!
- Popovers require the [tooltip plugin]({{ site.baseurl }}/docs/{{ site.docs_version }}/components/tooltips/) as a dependency.
- Popovers are opt-in for performance reasons, so **you must initialize them yourself**.
- Zero-length `title` and `content` values will never show a popover.
diff --git a/docs/4.0/components/tooltips.md b/docs/4.0/components/tooltips.md
index c6cf14dc9..7c0bd9f6a 100644
--- a/docs/4.0/components/tooltips.md
+++ b/docs/4.0/components/tooltips.md
@@ -10,7 +10,7 @@ toc: true
Things to know when using the tooltip plugin:
-- Tooltips rely on the 3rd party library [Popper.js](https://popper.js.org) for positioning. You must include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js) before bootstrap.js in order for tooltips to work!
+- Tooltips rely on the 3rd party library [Popper.js](https://popper.js.org) for positioning. You must include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.10.1/umd/popper.min.js) before bootstrap.js in order for tooltips to work!
- Tooltips are opt-in for performance reasons, so **you must initialize them yourself**.
- Tooltips with zero-length titles are never displayed.
- Specify `container: 'body'` to avoid rendering problems in more complex components (like our input groups, button groups, etc).
diff --git a/docs/4.0/examples/album/index.html b/docs/4.0/examples/album/index.html
index f30905813..f442be943 100644
--- a/docs/4.0/examples/album/index.html
+++ b/docs/4.0/examples/album/index.html
@@ -118,7 +118,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../assets/js/vendor/holder.min.js"></script>
<script>
$(function () {
diff --git a/docs/4.0/examples/blog/index.html b/docs/4.0/examples/blog/index.html
index c79abdde9..8225c246a 100644
--- a/docs/4.0/examples/blog/index.html
+++ b/docs/4.0/examples/blog/index.html
@@ -158,7 +158,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/carousel/index.html b/docs/4.0/examples/carousel/index.html
index 95a8bed58..451b4c38f 100644
--- a/docs/4.0/examples/carousel/index.html
+++ b/docs/4.0/examples/carousel/index.html
@@ -176,7 +176,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- Just to make our placeholder images work. Don't actually copy the next line! -->
<script src="../../../../assets/js/vendor/holder.min.js"></script>
diff --git a/docs/4.0/examples/cover/index.html b/docs/4.0/examples/cover/index.html
index 87efec4d7..7edfe51ed 100644
--- a/docs/4.0/examples/cover/index.html
+++ b/docs/4.0/examples/cover/index.html
@@ -60,7 +60,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/dashboard/index.html b/docs/4.0/examples/dashboard/index.html
index 01d94fba4..e535f19d1 100644
--- a/docs/4.0/examples/dashboard/index.html
+++ b/docs/4.0/examples/dashboard/index.html
@@ -254,7 +254,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/jumbotron/index.html b/docs/4.0/examples/jumbotron/index.html
index a2f4a7b71..15b449f78 100644
--- a/docs/4.0/examples/jumbotron/index.html
+++ b/docs/4.0/examples/jumbotron/index.html
@@ -93,7 +93,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/justified-nav/index.html b/docs/4.0/examples/justified-nav/index.html
index 4ebaeed06..16ac2a10b 100644
--- a/docs/4.0/examples/justified-nav/index.html
+++ b/docs/4.0/examples/justified-nav/index.html
@@ -96,7 +96,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/navbar-top-fixed/index.html b/docs/4.0/examples/navbar-top-fixed/index.html
index 5f81d4905..f27b42dd8 100644
--- a/docs/4.0/examples/navbar-top-fixed/index.html
+++ b/docs/4.0/examples/navbar-top-fixed/index.html
@@ -56,7 +56,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/navbar-top/index.html b/docs/4.0/examples/navbar-top/index.html
index 66f86f6bf..bdad69171 100644
--- a/docs/4.0/examples/navbar-top/index.html
+++ b/docs/4.0/examples/navbar-top/index.html
@@ -56,7 +56,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/navbars/index.html b/docs/4.0/examples/navbars/index.html
index de0a500fb..7b829a8b2 100644
--- a/docs/4.0/examples/navbars/index.html
+++ b/docs/4.0/examples/navbars/index.html
@@ -351,7 +351,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/offcanvas/index.html b/docs/4.0/examples/offcanvas/index.html
index d0581f997..89485ea62 100644
--- a/docs/4.0/examples/offcanvas/index.html
+++ b/docs/4.0/examples/offcanvas/index.html
@@ -127,7 +127,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/starter-template/index.html b/docs/4.0/examples/starter-template/index.html
index ce430a60d..d69f5a397 100644
--- a/docs/4.0/examples/starter-template/index.html
+++ b/docs/4.0/examples/starter-template/index.html
@@ -66,7 +66,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/sticky-footer-navbar/index.html b/docs/4.0/examples/sticky-footer-navbar/index.html
index aa1f046ad..4f5fe32dd 100644
--- a/docs/4.0/examples/sticky-footer-navbar/index.html
+++ b/docs/4.0/examples/sticky-footer-navbar/index.html
@@ -64,7 +64,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/tooltip-viewport/index.html b/docs/4.0/examples/tooltip-viewport/index.html
index f60ca4707..f44e98b0e 100644
--- a/docs/4.0/examples/tooltip-viewport/index.html
+++ b/docs/4.0/examples/tooltip-viewport/index.html
@@ -39,7 +39,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/migration.md b/docs/4.0/migration.md
index be861bac9..f1e6b9fe2 100644
--- a/docs/4.0/migration.md
+++ b/docs/4.0/migration.md
@@ -103,8 +103,11 @@ New to Bootstrap 4 is the [Reboot]({{ site.baseurl }}/docs/{{ site.docs_version
- Dropped the `.form-horizontal` class requirement.
- `.form-group` no longer applies styles from the `.row` via mixin, so `.row` is now required for horizontal grid layouts (e.g., `<div class="form-group row">`).
- Added new `.form-control-label` class to vertically center labels with `.form-control`s.
+ - Added new `.form-row` for compact form layouts with the grid classes (swap your `.row` for a `.form-row` and go).
- Added custom forms support (for checkboxes, radios, selects, and file inputs).
+- Added HTML5 form validation support via CSS's `:invalid` and `:valid` pseudo-classes.
- Renamed `.has-error` to `.has-danger`.
+- Renamed `.form-control-static` to `.form-control-plaintext`.
### Buttons