0
0
mirror of https://github.com/twbs/bootstrap.git synced 2024-12-01 13:24:25 +01:00

Merge pull request #19141 from twbs/v4-forms-cleanup

v4: Forms cleanup
This commit is contained in:
Mark Otto 2016-05-11 10:49:31 -07:00
commit 9d6b41c127
16 changed files with 420 additions and 475 deletions

View File

@ -477,6 +477,18 @@ textarea {
border-radius: 0;
}
input[type="radio"]:disabled,
input[type="checkbox"]:disabled {
cursor: not-allowed;
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
resize: vertical;
}
@ -2174,59 +2186,31 @@ select.form-control:focus::-ms-value {
display: block;
}
.form-control-label {
padding: 0.5rem 0.75rem;
.col-form-label {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
margin-bottom: 0;
}
.form-control-legend {
padding: 0.5rem 0.75rem;
.col-form-label-lg {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
font-size: 1.25rem;
}
.col-form-label-sm {
padding-top: 0.25rem;
padding-bottom: 0.25rem;
font-size: 0.875rem;
}
.col-form-legend {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
margin-bottom: 0;
font-size: 1rem;
}
_::-webkit-full-page-media.form-control,
input[type="date"].form-control,
input[type="time"].form-control,
input[type="datetime-local"].form-control,
input[type="month"].form-control {
line-height: 2.5rem;
}
_::-webkit-full-page-media.input-sm,
.input-group-sm _::-webkit-full-page-media.form-control,
input[type="date"].input-sm,
.input-group-sm
input[type="date"].form-control,
input[type="time"].input-sm,
.input-group-sm
input[type="time"].form-control,
input[type="datetime-local"].input-sm,
.input-group-sm
input[type="datetime-local"].form-control,
input[type="month"].input-sm,
.input-group-sm
input[type="month"].form-control {
line-height: 1.8125rem;
}
_::-webkit-full-page-media.input-lg,
.input-group-lg _::-webkit-full-page-media.form-control,
input[type="date"].input-lg,
.input-group-lg
input[type="date"].form-control,
input[type="time"].input-lg,
.input-group-lg
input[type="time"].form-control,
input[type="datetime-local"].input-lg,
.input-group-lg
input[type="datetime-local"].form-control,
input[type="month"].input-lg,
.input-group-lg
input[type="month"].form-control {
line-height: 3.166667rem;
}
.form-control-static {
min-height: 2.5rem;
padding-top: 0.5rem;
@ -2251,6 +2235,12 @@ input[type="month"].form-control {
border-radius: 0.2rem;
}
select.form-control-sm:not([size]):not([multiple]), .input-group-sm > select.form-control:not([size]):not([multiple]),
.input-group-sm > select.input-group-addon:not([size]):not([multiple]),
.input-group-sm > .input-group-btn > select.btn:not([size]):not([multiple]) {
height: 1.8125rem;
}
.form-control-lg, .input-group-lg > .form-control,
.input-group-lg > .input-group-addon,
.input-group-lg > .input-group-btn > .btn {
@ -2259,45 +2249,48 @@ input[type="month"].form-control {
border-radius: 0.3rem;
}
select.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.form-control:not([size]):not([multiple]),
.input-group-lg > select.input-group-addon:not([size]):not([multiple]),
.input-group-lg > .input-group-btn > select.btn:not([size]):not([multiple]) {
height: 3.166667rem;
}
.form-group {
margin-bottom: 1rem;
}
.radio,
.checkbox {
.form-check {
position: relative;
display: block;
margin-bottom: 0.75rem;
}
.radio label,
.checkbox label {
.form-check + .form-check {
margin-top: -.25rem;
}
.form-check.disabled .form-check-label {
color: #818a91;
cursor: not-allowed;
}
.form-check-label {
padding-left: 1.25rem;
margin-bottom: 0;
cursor: pointer;
}
.radio label input:only-child,
.checkbox label input:only-child {
position: static;
}
.radio input[type="radio"],
.radio-inline input[type="radio"],
.checkbox input[type="checkbox"],
.checkbox-inline input[type="checkbox"] {
.form-check-input {
position: absolute;
margin-top: .25rem;
margin-left: -1.25rem;
}
.radio + .radio,
.checkbox + .checkbox {
margin-top: -.25rem;
.form-check-input:only-child {
position: static;
}
.radio-inline,
.checkbox-inline {
.form-check-inline {
position: relative;
display: inline-block;
padding-left: 1.25rem;
@ -2306,26 +2299,16 @@ input[type="month"].form-control {
cursor: pointer;
}
.radio-inline + .radio-inline,
.checkbox-inline + .checkbox-inline {
margin-top: 0;
.form-check-inline + .form-check-inline {
margin-left: .75rem;
}
input[type="radio"]:disabled, input[type="radio"].disabled,
input[type="checkbox"]:disabled,
input[type="checkbox"].disabled {
.form-check-inline.disabled {
cursor: not-allowed;
}
.radio-inline.disabled,
.checkbox-inline.disabled {
cursor: not-allowed;
}
.radio.disabled label,
.checkbox.disabled label {
cursor: not-allowed;
.form-control-feedback {
margin-top: .5rem;
}
.form-control-success,
@ -2338,7 +2321,7 @@ input[type="checkbox"].disabled {
background-size: 1.25rem 1.25rem;
}
.has-success .text-help,
.has-success .form-control-feedback,
.has-success .form-control-label,
.has-success .radio,
.has-success .checkbox,
@ -2370,7 +2353,7 @@ input[type="checkbox"].disabled {
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%235cb85c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");
}
.has-warning .text-help,
.has-warning .form-control-feedback,
.has-warning .form-control-label,
.has-warning .radio,
.has-warning .checkbox,
@ -2402,7 +2385,7 @@ input[type="checkbox"].disabled {
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23f0ad4e' d='M4.4 5.324h-.8v-2.46h.8zm0 1.42h-.8V5.89h.8zM3.76.63L.04 7.075c-.115.2.016.425.26.426h7.397c.242 0 .372-.226.258-.426C6.726 4.924 5.47 2.79 4.253.63c-.113-.174-.39-.174-.494 0z'/%3E%3C/svg%3E");
}
.has-danger .text-help,
.has-danger .form-control-feedback,
.has-danger .form-control-label,
.has-danger .radio,
.has-danger .checkbox,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -128,6 +128,10 @@
position: static;
display: block;
}
> .form-group:last-child {
margin-bottom: 0;
}
}
.bd-example > .close {

View File

@ -22,7 +22,7 @@ Remember, since Bootstrap utilizes the HTML5 doctype, **all inputs must have a `
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email">
<small id="emailHelp" class="text-muted">We'll never share your email with anyone else.</small>
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
@ -55,7 +55,7 @@ Remember, since Bootstrap utilizes the HTML5 doctype, **all inputs must have a `
<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="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>
<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>
</div>
<fieldset class="form-group">
<legend>Radio buttons</legend>
@ -172,79 +172,79 @@ Here are examples of `.form-control` applied to each textual HTML5 `<input>` `ty
{% example html %}
<div class="form-group row">
<label for="example-text-input" class="col-xs-2 form-control-label">Text</label>
<label for="example-text-input" class="col-xs-2 col-form-label">Text</label>
<div class="col-xs-10">
<input class="form-control" type="text" value="Artisanal kale" id="example-text-input">
</div>
</div>
<div class="form-group row">
<label for="example-search-input" class="col-xs-2 form-control-label">Search</label>
<label for="example-search-input" class="col-xs-2 col-form-label">Search</label>
<div class="col-xs-10">
<input class="form-control" type="search" value="How do I shoot web" id="example-search-input">
</div>
</div>
<div class="form-group row">
<label for="example-email-input" class="col-xs-2 form-control-label">Email</label>
<label for="example-email-input" class="col-xs-2 col-form-label">Email</label>
<div class="col-xs-10">
<input class="form-control" type="email" value="bootstrap@example.com" id="example-email-input">
</div>
</div>
<div class="form-group row">
<label for="example-url-input" class="col-xs-2 form-control-label">URL</label>
<label for="example-url-input" class="col-xs-2 col-form-label">URL</label>
<div class="col-xs-10">
<input class="form-control" type="url" value="http://getbootstrap.com" id="example-url-input">
</div>
</div>
<div class="form-group row">
<label for="example-tel-input" class="col-xs-2 form-control-label">Telephone</label>
<label for="example-tel-input" class="col-xs-2 col-form-label">Telephone</label>
<div class="col-xs-10">
<input class="form-control" type="tel" value="1-(555)-555-5555" id="example-tel-input">
</div>
</div>
<div class="form-group row">
<label for="example-password-input" class="col-xs-2 form-control-label">Password</label>
<label for="example-password-input" class="col-xs-2 col-form-label">Password</label>
<div class="col-xs-10">
<input class="form-control" type="password" value="hunter2" id="example-password-input">
</div>
</div>
<div class="form-group row">
<label for="example-number-input" class="col-xs-2 form-control-label">Number</label>
<label for="example-number-input" class="col-xs-2 col-form-label">Number</label>
<div class="col-xs-10">
<input class="form-control" type="number" value="42" id="example-number-input">
</div>
</div>
<div class="form-group row">
<label for="example-datetime-local-input" class="col-xs-2 form-control-label">Date and time</label>
<label for="example-datetime-local-input" class="col-xs-2 col-form-label">Date and time</label>
<div class="col-xs-10">
<input class="form-control" type="datetime-local" value="2011-08-19T13:45:00" id="example-datetime-local-input">
</div>
</div>
<div class="form-group row">
<label for="example-date-input" class="col-xs-2 form-control-label">Date</label>
<label for="example-date-input" class="col-xs-2 col-form-label">Date</label>
<div class="col-xs-10">
<input class="form-control" type="date" value="2011-08-19" id="example-date-input">
</div>
</div>
<div class="form-group row">
<label for="example-month-input" class="col-xs-2 form-control-label">Month</label>
<label for="example-month-input" class="col-xs-2 col-form-label">Month</label>
<div class="col-xs-10">
<input class="form-control" type="month" value="2011-08" id="example-month-input">
</div>
</div>
<div class="form-group row">
<label for="example-week-input" class="col-xs-2 form-control-label">Week</label>
<label for="example-week-input" class="col-xs-2 col-form-label">Week</label>
<div class="col-xs-10">
<input class="form-control" type="week" value="2011-W33" id="example-week-input">
</div>
</div>
<div class="form-group row">
<label for="example-time-input" class="col-xs-2 form-control-label">Time</label>
<label for="example-time-input" class="col-xs-2 col-form-label">Time</label>
<div class="col-xs-10">
<input class="form-control" type="time" value="13:45:00" id="example-time-input">
</div>
</div>
<div class="form-group row">
<label for="example-color-input" class="col-xs-2 form-control-label">Color</label>
<label for="example-color-input" class="col-xs-2 col-form-label">Color</label>
<div class="col-xs-10">
<input class="form-control" type="color" value="#563d7c" id="example-color-input">
</div>
@ -310,9 +310,9 @@ Because of this, you may need to manually address the width and alignment of ind
<label class="sr-only" for="exampleInputPassword3">Password</label>
<input type="password" class="form-control" id="exampleInputPassword3" placeholder="Password">
</div>
<div class="checkbox">
<label>
<input type="checkbox"> Remember me
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="checkbox"> Remember me
</label>
</div>
<button type="submit" class="btn btn-primary">Sign in</button>
@ -334,108 +334,136 @@ Because of this, you may need to manually address the width and alignment of ind
{% 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 %}
#### 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
For more structured form layouts, you can utilize Bootstrap's predefined grid classes (or 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.
For more structured form layouts that are also responsive, you can utilize Bootstrap's [predefined grid classes](/layout/grid/#predefined-classes) or [mixins](/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.
Be sure to add `.form-control-label` to your `<label>`s as well so they're vertically centered with their associated form controls. For `<legend>` elements, you can use `.form-control-legend` to make them appear similar to regular `<label>` elements.
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.
{% example html %}
<form>
<div class="form-group row">
<label for="inputEmail3" class="col-sm-2 form-control-label">Email</label>
<div class="col-sm-10">
<input type="email" class="form-control" id="inputEmail3" placeholder="Email">
</div>
</div>
<div class="form-group row">
<label for="inputPassword3" class="col-sm-2 form-control-label">Password</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="inputPassword3" placeholder="Password">
</div>
</div>
<fieldset class="form-group row">
<legend class="col-sm-2 form-control-legend">Radios</legend>
<div class="col-sm-10">
<div class="radio">
<label>
<input type="radio" name="gridRadios" id="gridRadios1" value="option1" checked>
Option one is this and that&mdash;be sure to include why it's great
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="gridRadios" id="gridRadios2" value="option2">
Option two can be something else and selecting it will deselect option one
</label>
</div>
<div class="radio disabled">
<label>
<input type="radio" name="gridRadios" id="gridRadios3" value="option3" disabled>
Option three is disabled
</label>
<div class="container">
<form>
<div class="form-group 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" placeholder="Email">
</div>
</div>
</fieldset>
<fieldset class="form-group row">
<legend class="col-sm-2 form-control-legend">Checkbox</legend>
<div class="col-sm-10">
<div class="checkbox">
<label>
<input type="checkbox"> Check me out
</label>
<div class="form-group 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" placeholder="Password">
</div>
</div>
</fieldset>
<div class="form-group row">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-secondary">Sign in</button>
<fieldset class="form-group row">
<legend class="col-form-legend col-sm-2">Radios</legend>
<div class="col-sm-10">
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="radio" name="gridRadios" id="gridRadios1" 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="gridRadios" id="gridRadios2" 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="gridRadios" id="gridRadios3" value="option3" disabled>
Option three is disabled
</label>
</div>
</div>
</fieldset>
<div class="form-group row">
<label class="col-sm-2">Checkbox</label>
<div class="col-sm-10">
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="checkbox"> Check me out
</label>
</div>
</div>
</div>
</div>
</form>
<div class="form-group row">
<div class="offset-sm-2 col-sm-10">
<button type="submit" class="btn btn-primary">Sign in</button>
</div>
</div>
</form>
</div>
{% endexample %}
Grid-based form layouts also support large and small inputs.
{% 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="you@example.com">
</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="you@example.com">
</div>
</div>
</form>
</div>
{% endexample %}
## Checkboxes and radios
Checkboxes are for selecting one or several options in a list, while radios are for selecting one option from many.
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 <code>.disabled</code> class to the parent `.radio`, `.radio-inline`, `.checkbox`, or `.checkbox-inline`.
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="checkbox">
<label>
<input type="checkbox" value="">
<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="checkbox disabled">
<label>
<input type="checkbox" value="" disabled>
<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 %}
<div class="radio">
<label>
<input type="radio" name="exampleRadios" id="exampleRadios1" value="option1" checked>
{% 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="radio">
<label>
<input type="radio" name="exampleRadios" id="exampleRadios2" value="option2">
<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="radio disabled">
<label>
<input type="radio" name="exampleRadios" id="exampleRadios3" value="option3" disabled>
<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>
@ -443,29 +471,29 @@ Disabled checkboxes and radios are supported, but to provide a "not-allowed" cur
### Inline
Use the `.checkbox-inline` or `.radio-inline` classes on a series of checkboxes or radios for controls that appear on the same line.
Groups of checkboxes or radios that appear on the same horizontal row are similar to their stacked counterparts, but require different HTML and a single class. To switch from stacked to inline, drop the surrounding `<div>`, add `.form-check-inline` to the `<label>`, and keep the `.form-check-input` on the `<input>`.
{% example html %}
<label class="checkbox-inline">
<input type="checkbox" id="inlineCheckbox1" value="option1"> 1
<label class="form-check-inline">
<input class="form-check-input" type="checkbox" id="inlineCheckbox1" value="option1"> 1
</label>
<label class="checkbox-inline">
<input type="checkbox" id="inlineCheckbox2" value="option2"> 2
<label class="form-check-inline">
<input class="form-check-input" type="checkbox" id="inlineCheckbox2" value="option2"> 2
</label>
<label class="checkbox-inline">
<input type="checkbox" id="inlineCheckbox3" value="option3"> 3
<label class="form-check-inline">
<input class="form-check-input" type="checkbox" id="inlineCheckbox3" value="option3"> 3
</label>
{% endexample %}
{% example html %}
<label class="radio-inline">
<input type="radio" name="inlineRadioOptions" id="inlineRadio1" value="option1"> 1
<label class="form-check-inline">
<input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio1" value="option1"> 1
</label>
<label class="radio-inline">
<input type="radio" name="inlineRadioOptions" id="inlineRadio2" value="option2"> 2
<label class="form-check-inline">
<input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio2" value="option2"> 2
</label>
<label class="radio-inline">
<input type="radio" name="inlineRadioOptions" id="inlineRadio3" value="option3"> 3
<label class="form-check-inline">
<input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio3" value="option3"> 3
</label>
{% endexample %}
@ -474,14 +502,14 @@ Use the `.checkbox-inline` or `.radio-inline` classes on a series of checkboxes
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="checkbox">
<label>
<input type="checkbox" id="blankCheckbox" value="option1" aria-label="...">
<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="radio">
<label>
<input type="radio" name="blankRadio" id="blankRadio1" value="option1" aria-label="...">
<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 %}
@ -493,13 +521,13 @@ When you need to place plain text next to a form label within a form, use the `.
{% example html %}
<form>
<div class="form-group row">
<label class="col-sm-2 form-control-label">Email</label>
<label class="col-sm-2 col-form-label">Email</label>
<div class="col-sm-10">
<p class="form-control-static">email@example.com</p>
</div>
</div>
<div class="form-group row">
<label for="inputPassword" class="col-sm-2 form-control-label">Password</label>
<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>
@ -585,9 +613,15 @@ Set heights using classes like `.form-control-lg`, and set widths using grid col
{% endexample %}
{% example html %}
<select class="form-control form-control-lg"></select>
<select class="form-control"></select>
<select class="form-control form-control-sm"></select>
<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 %}
## Column sizing
@ -610,7 +644,7 @@ Wrap inputs in grid columns, or any custom parent element, to easily enforce des
## Help text
No official help text classes exist in Bootstrap 4 (previously we had `.help-block` in v3), but thanks to our utility classes like `.text-muted`, you can create much more flexible help text as you need it.
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
@ -618,6 +652,20 @@ No official help text classes exist in Bootstrap 4 (previously we had `.help-blo
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.
{% 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>
{% endexample %}
### Inline
Inline text can use any typical inline HTML element (be it a `<small>`, `<span>`, or something else).
{% example html %}
@ -632,25 +680,24 @@ Inline text can use any typical inline HTML element (be it a `<small>`, `<span>`
</form>
{% endexample %}
Block help text—for below inputs or for longer lines of help text—can be easily achieved with a `<p>`.
{% example html %}
<label for="inputPassword5">Password</label>
<input type="password" id="inputPassword5" class="form-control" aria-describedby="passwordHelpBlock">
<p id="passwordHelpBlock" class="text-muted">
Your password must be 8-20 characters long, contain letters and numbers, and must not contain spaces, special characters or emoji.
</p>
{% endexample %}
## Validation
Bootstrap includes validation styles for danger, warning, and success states on form controls.
Bootstrap includes validation styles for danger, warning, and success states on form controls. Here's a rundown of how they work:
- To use, add `.has-warning`, `.has-danger`, or `.has-success` to the parent element. Any `.form-control-label`, `.form-control`, and `.text-help` within that element will receive the validation styles.
- 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.
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.
Here are some examples of the aforementioned classes in action.
{% comment %}
{% callout warning %}
#### Conveying validation state to assistive technologies and colorblind users
@ -663,18 +710,26 @@ Ensure that an alternative indication of state is also provided. For instance, y
{% example html %}
<div class="form-group has-success">
<label class="form-control-label" for="inputSuccess1">Input with success</label>
<label class="col-form-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>
<label class="col-form-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>
<label class="col-form-label" for="inputDanger1">Input with danger</label>
<input type="text" class="form-control form-control-danger" id="inputDanger1">
<div class="form-control-feedback">Shit, that username's taken. Try another?</div>
<small class="form-text text-muted">Example help text that remains unchanged.</small>
</div>
{% endexample %}
{% example html %}
<div class="checkbox has-success">
<label>
<input type="checkbox" id="checkboxSuccess" value="option1">

View File

@ -477,6 +477,18 @@ textarea {
border-radius: 0;
}
input[type="radio"]:disabled,
input[type="checkbox"]:disabled {
cursor: not-allowed;
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
resize: vertical;
}
@ -2174,59 +2186,31 @@ select.form-control:focus::-ms-value {
display: block;
}
.form-control-label {
padding: 0.5rem 0.75rem;
.col-form-label {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
margin-bottom: 0;
}
.form-control-legend {
padding: 0.5rem 0.75rem;
.col-form-label-lg {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
font-size: 1.25rem;
}
.col-form-label-sm {
padding-top: 0.25rem;
padding-bottom: 0.25rem;
font-size: 0.875rem;
}
.col-form-legend {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
margin-bottom: 0;
font-size: 1rem;
}
_::-webkit-full-page-media.form-control,
input[type="date"].form-control,
input[type="time"].form-control,
input[type="datetime-local"].form-control,
input[type="month"].form-control {
line-height: 2.5rem;
}
_::-webkit-full-page-media.input-sm,
.input-group-sm _::-webkit-full-page-media.form-control,
input[type="date"].input-sm,
.input-group-sm
input[type="date"].form-control,
input[type="time"].input-sm,
.input-group-sm
input[type="time"].form-control,
input[type="datetime-local"].input-sm,
.input-group-sm
input[type="datetime-local"].form-control,
input[type="month"].input-sm,
.input-group-sm
input[type="month"].form-control {
line-height: 1.8125rem;
}
_::-webkit-full-page-media.input-lg,
.input-group-lg _::-webkit-full-page-media.form-control,
input[type="date"].input-lg,
.input-group-lg
input[type="date"].form-control,
input[type="time"].input-lg,
.input-group-lg
input[type="time"].form-control,
input[type="datetime-local"].input-lg,
.input-group-lg
input[type="datetime-local"].form-control,
input[type="month"].input-lg,
.input-group-lg
input[type="month"].form-control {
line-height: 3.166667rem;
}
.form-control-static {
min-height: 2.5rem;
padding-top: 0.5rem;
@ -2251,6 +2235,12 @@ input[type="month"].form-control {
border-radius: 0.2rem;
}
select.form-control-sm:not([size]):not([multiple]), .input-group-sm > select.form-control:not([size]):not([multiple]),
.input-group-sm > select.input-group-addon:not([size]):not([multiple]),
.input-group-sm > .input-group-btn > select.btn:not([size]):not([multiple]) {
height: 1.8125rem;
}
.form-control-lg, .input-group-lg > .form-control,
.input-group-lg > .input-group-addon,
.input-group-lg > .input-group-btn > .btn {
@ -2259,45 +2249,48 @@ input[type="month"].form-control {
border-radius: 0.3rem;
}
select.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.form-control:not([size]):not([multiple]),
.input-group-lg > select.input-group-addon:not([size]):not([multiple]),
.input-group-lg > .input-group-btn > select.btn:not([size]):not([multiple]) {
height: 3.166667rem;
}
.form-group {
margin-bottom: 1rem;
}
.radio,
.checkbox {
.form-check {
position: relative;
display: block;
margin-bottom: 0.75rem;
}
.radio label,
.checkbox label {
.form-check + .form-check {
margin-top: -.25rem;
}
.form-check.disabled .form-check-label {
color: #818a91;
cursor: not-allowed;
}
.form-check-label {
padding-left: 1.25rem;
margin-bottom: 0;
cursor: pointer;
}
.radio label input:only-child,
.checkbox label input:only-child {
position: static;
}
.radio input[type="radio"],
.radio-inline input[type="radio"],
.checkbox input[type="checkbox"],
.checkbox-inline input[type="checkbox"] {
.form-check-input {
position: absolute;
margin-top: .25rem;
margin-left: -1.25rem;
}
.radio + .radio,
.checkbox + .checkbox {
margin-top: -.25rem;
.form-check-input:only-child {
position: static;
}
.radio-inline,
.checkbox-inline {
.form-check-inline {
position: relative;
display: inline-block;
padding-left: 1.25rem;
@ -2306,26 +2299,16 @@ input[type="month"].form-control {
cursor: pointer;
}
.radio-inline + .radio-inline,
.checkbox-inline + .checkbox-inline {
margin-top: 0;
.form-check-inline + .form-check-inline {
margin-left: .75rem;
}
input[type="radio"]:disabled, input[type="radio"].disabled,
input[type="checkbox"]:disabled,
input[type="checkbox"].disabled {
.form-check-inline.disabled {
cursor: not-allowed;
}
.radio-inline.disabled,
.checkbox-inline.disabled {
cursor: not-allowed;
}
.radio.disabled label,
.checkbox.disabled label {
cursor: not-allowed;
.form-control-feedback {
margin-top: .5rem;
}
.form-control-success,
@ -2338,7 +2321,7 @@ input[type="checkbox"].disabled {
background-size: 1.25rem 1.25rem;
}
.has-success .text-help,
.has-success .form-control-feedback,
.has-success .form-control-label,
.has-success .radio,
.has-success .checkbox,
@ -2370,7 +2353,7 @@ input[type="checkbox"].disabled {
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%235cb85c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");
}
.has-warning .text-help,
.has-warning .form-control-feedback,
.has-warning .form-control-label,
.has-warning .radio,
.has-warning .checkbox,
@ -2402,7 +2385,7 @@ input[type="checkbox"].disabled {
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23f0ad4e' d='M4.4 5.324h-.8v-2.46h.8zm0 1.42h-.8V5.89h.8zM3.76.63L.04 7.075c-.115.2.016.425.26.426h7.397c.242 0 .372-.226.258-.426C6.726 4.924 5.47 2.79 4.253.63c-.113-.174-.39-.174-.494 0z'/%3E%3C/svg%3E");
}
.has-danger .text-help,
.has-danger .form-control-feedback,
.has-danger .form-control-label,
.has-danger .radio,
.has-danger .checkbox,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -87,7 +87,7 @@ New to Bootstrap 4 is the Reboot, a new stylesheet that builds on Normalize with
- Renamed `.control-label` to `.form-control-label`.
- Renamed `.input-lg` and `.input-sm` to `.form-control-lg` and `.form-control-sm`, respectively.
- Dropped `.form-group-*` classes for simplicity's sake. Use `.form-control-*` classes instead now.
- Dropped `.help-block`; superseded by the `.text-muted` utility class to reduce duplicate code.
- Dropped `.help-block` and replaced it with `.form-text` for block-level help text. For inline help text and other flexible options, use utility classes like `.text-muted`.
- Horizontal forms overhauled:
- 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">`).

View File

@ -85,56 +85,39 @@ select.form-control {
// For use with horizontal and inline forms, when you need the label text to
// align with the form controls.
.form-control-label {
padding: $input-padding-y $input-padding-x;
.col-form-label {
padding-top: $input-padding-y;
padding-bottom: $input-padding-y;
margin-bottom: 0; // Override the `<label>` default
}
.col-form-label-lg {
padding-top: $input-padding-y-lg;
padding-bottom: $input-padding-y-lg;
font-size: $font-size-lg;
}
.col-form-label-sm {
padding-top: $input-padding-y-sm;
padding-bottom: $input-padding-y-sm;
font-size: $font-size-sm;
}
//
// Legends
//
// For use with horizontal and inline forms, when you need the legend text to
// be the same size as regular labels, and to align with the form controls.
.form-control-legend {
padding: $input-padding-y $input-padding-x;
.col-form-legend {
padding-top: $input-padding-y;
padding-bottom: $input-padding-y;
margin-bottom: 0;
font-size: $font-size-base;
}
// Todo: clear this up
// Special styles for iOS temporal inputs
//
// In Mobile Safari, setting `display: block` on temporal inputs causes the
// text within the input to become vertically misaligned. As a workaround, we
// set a pixel line-height that matches the given height of the input, but only
// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848
//
// Note that as of 8.3, iOS doesn't support `week`.
_::-webkit-full-page-media, // Hack to make this CSS be Safari-only; see http://browserbu.gs/css-hacks/webkit-full-page-media/
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
&.form-control {
line-height: $input-height;
}
&.input-sm,
.input-group-sm &.form-control {
line-height: $input-height-sm;
}
&.input-lg,
.input-group-lg &.form-control {
line-height: $input-height-lg;
}
}
// Static form control text
//
// Apply class to an element to make any string of text align with labels in a
@ -170,12 +153,24 @@ input[type="month"] {
@include border-radius($input-border-radius-sm);
}
select.form-control-sm {
&:not([size]):not([multiple]) {
height: $input-height-sm;
}
}
.form-control-lg {
padding: $input-padding-y-lg $input-padding-x-lg;
font-size: $font-size-lg;
@include border-radius($input-border-radius-lg);
}
select.form-control-lg {
&:not([size]):not([multiple]) {
height: $input-height-lg;
}
}
// Form groups
//
@ -186,94 +181,77 @@ input[type="month"] {
margin-bottom: $form-group-margin-bottom;
}
.form-text {
display: block;
margin-top: ($spacer * .25);
}
// Checkboxes and radios
//
// Indent the labels to position radios/checkboxes as hanging controls.
.radio,
.checkbox {
.form-check {
position: relative;
display: block;
// margin-top: ($spacer * .75);
margin-bottom: ($spacer * .75);
label {
padding-left: 1.25rem;
margin-bottom: 0;
cursor: pointer;
// Move up sibling radios or checkboxes for tighter spacing
+ .form-check {
margin-top: -.25rem;
}
// When there's no labels, don't position the input.
input:only-child {
position: static;
&.disabled {
.form-check-label {
color: $text-muted;
cursor: $cursor-disabled;
}
}
}
.radio input[type="radio"],
.radio-inline input[type="radio"],
.checkbox input[type="checkbox"],
.checkbox-inline input[type="checkbox"] {
position: absolute;
margin-top: .25rem;
// margin-top: 4px \9;
margin-left: -1.25rem;
.form-check-label {
padding-left: 1.25rem;
margin-bottom: 0; // Override default `<label>` bottom margin
cursor: pointer;
}
.radio + .radio,
.checkbox + .checkbox {
// Move up sibling radios or checkboxes for tighter spacing
margin-top: -.25rem;
.form-check-input {
position: absolute;
margin-top: .25rem;
margin-left: -1.25rem;
&:only-child {
position: static;
}
}
// Radios and checkboxes on same line
.radio-inline,
.checkbox-inline {
.form-check-inline {
position: relative;
display: inline-block;
padding-left: 1.25rem;
margin-bottom: 0;
margin-bottom: 0; // Override default `<label>` bottom margin
vertical-align: middle;
cursor: pointer;
}
.radio-inline + .radio-inline,
.checkbox-inline + .checkbox-inline {
margin-top: 0;
margin-left: .75rem;
}
// Apply same disabled cursor tweak as for inputs
// Some special care is needed because <label>s don't inherit their parent's `cursor`.
//
// Note: Neither radios nor checkboxes can be readonly.
input[type="radio"],
input[type="checkbox"] {
&:disabled,
+ .form-check-inline {
margin-left: .75rem;
}
&.disabled {
cursor: $cursor-disabled;
}
}
// These classes are used directly on <label>s
.radio-inline,
.checkbox-inline {
&.disabled {
cursor: $cursor-disabled;
}
}
// These classes are used on elements with <label> descendants
.radio,
.checkbox {
&.disabled {
label {
cursor: $cursor-disabled;
}
}
}
// Form control feedback states
//
// Apply contextual and semantic states to individual form controls.
.form-control-feedback {
margin-top: ($spacer * .25);
}
.form-control-success,
.form-control-warning,
.form-control-danger {
@ -309,84 +287,6 @@ input[type="checkbox"] {
}
// .form-control-success {
// background-image: $form-icon-success;
// border-color: $brand-success;
// }
//
// .form-control-warning {
// background-image: $form-icon-warning;
// border-color: $brand-warning;
// }
//
// .form-control-error {
// background-image: $form-icon-danger;
// border-color: $brand-danger;
// }
// .has-feedback {
// // Enable absolute positioning
// position: relative;
//
// // Ensure icons don't overlap text
// .form-control {
// padding-right: ($input-height * 1.25);
// }
// }
// // Feedback icon
// .form-control-feedback {
// position: absolute;
// top: 0;
// right: 0;
// z-index: 2; // Ensure icon is above input groups
// display: block;
// width: $input-height;
// height: $input-height;
// line-height: $input-height;
// text-align: center;
// pointer-events: none;
// }
// .input-lg + .form-control-feedback,
// .input-group-lg + .form-control-feedback {
// width: $input-height-lg;
// height: $input-height-lg;
// line-height: $input-height-lg;
// }
// .input-sm + .form-control-feedback,
// .input-group-sm + .form-control-feedback {
// width: $input-height-sm;
// height: $input-height-sm;
// line-height: $input-height-sm;
// }
//
// // Form validation states
// .has-success {
// @include form-control-validation($state-success-text, $state-success-text, $state-success-bg);
// }
// .has-warning {
// @include form-control-validation($state-warning-text, $state-warning-text, $state-warning-bg);
// }
// .has-danger {
// @include form-control-validation($state-danger-text, $state-danger-text, $state-danger-bg);
// }
//
// // Reposition feedback icon if input has visible label above
// .has-feedback label {
//
// ~ .form-control-feedback {
// // TODO: redo this since we nuked the `$line-height-computed`
// top: 0; // Height of the `label` and its margin
// }
//
// &.sr-only ~ .form-control-feedback {
// top: 0;
// }
// }
// Inline forms
//
// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
@ -442,19 +342,16 @@ input[type="checkbox"] {
// Remove default margin on radios/checkboxes that were used for stacking, and
// then undo the floating of radios and checkboxes to match.
.radio,
.checkbox {
.form-check {
display: inline-block;
margin-top: 0;
margin-bottom: 0;
vertical-align: middle;
label {
padding-left: 0;
}
}
.radio input[type="radio"],
.checkbox input[type="checkbox"] {
.form-check-label {
padding-left: 0;
}
.form-check-input {
position: relative;
margin-left: 0;
}

View File

@ -321,6 +321,29 @@ textarea {
border-radius: 0;
}
input[type="radio"],
input[type="checkbox"] {
// Apply a disabled cursor for radios and checkboxes.
//
// Note: Neither radios nor checkboxes can be readonly.
&:disabled {
cursor: $cursor-disabled;
}
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
// Remove the default appearance of temporal inputs to avoid a Mobile Safari
// bug where setting a custom line-height prevents text from being vertically
// centered within the input.
//
// Bug report: https://github.com/twbs/bootstrap/issues/11266
-webkit-appearance: listbox;
}
textarea {
// Textareas should really only resize vertically so they don't break their (horizontal) containers.
resize: vertical;

View File

@ -5,7 +5,7 @@
@mixin form-control-validation($color) {
// Color the label and help text
.text-help,
.form-control-feedback,
.form-control-label,
.radio,
.checkbox,