0
0
mirror of https://github.com/twbs/bootstrap.git synced 2025-02-17 14:54:30 +01:00

Rewrite input group component (#25020)

* Rewrite input group component

* Set the feedback to 100% width for input group

* Move from .row to .form-row for tighter layout

* no need for custom feedback here, we're using browser messaging

* add input group to validation examples

* add note about validating multiple

* migration note added
This commit is contained in:
Mark Otto 2017-12-22 15:29:49 -08:00 committed by GitHub
parent 5cede31469
commit 13150872c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 353 additions and 337 deletions

View File

@ -60,7 +60,9 @@ Feel free to mix input groups with button groups in your toolbars. Similar to th
<button type="button" class="btn btn-secondary">4</button> <button type="button" class="btn btn-secondary">4</button>
</div> </div>
<div class="input-group"> <div class="input-group">
<span class="input-group-addon" id="btnGroupAddon">@</span> <div class="input-group-prepend">
<div class="input-group-text" id="btnGroupAddon">@</div>
</div>
<input type="text" class="form-control" placeholder="Input group example" aria-label="Input group example" aria-describedby="btnGroupAddon"> <input type="text" class="form-control" placeholder="Input group example" aria-label="Input group example" aria-describedby="btnGroupAddon">
</div> </div>
</div> </div>
@ -73,7 +75,9 @@ Feel free to mix input groups with button groups in your toolbars. Similar to th
<button type="button" class="btn btn-secondary">4</button> <button type="button" class="btn btn-secondary">4</button>
</div> </div>
<div class="input-group"> <div class="input-group">
<span class="input-group-addon" id="btnGroupAddon2">@</span> <div class="input-group-prepend">
<div class="input-group-text" id="btnGroupAddon2">@</div>
</div>
<input type="text" class="form-control" placeholder="Input group example" aria-label="Input group example" aria-describedby="btnGroupAddon2"> <input type="text" class="form-control" placeholder="Input group example" aria-label="Input group example" aria-describedby="btnGroupAddon2">
</div> </div>
</div> </div>

View File

@ -482,7 +482,9 @@ The example below uses a flexbox utility to vertically center the contents and c
<div class="col-auto"> <div class="col-auto">
<label class="sr-only" for="inlineFormInputGroup">Username</label> <label class="sr-only" for="inlineFormInputGroup">Username</label>
<div class="input-group mb-2"> <div class="input-group mb-2">
<div class="input-group-addon">@</div> <div class="input-group-prepend">
<div class="input-group-text">@</div>
</div>
<input type="text" class="form-control" id="inlineFormInputGroup" placeholder="Username"> <input type="text" class="form-control" id="inlineFormInputGroup" placeholder="Username">
</div> </div>
</div> </div>
@ -512,7 +514,9 @@ You can then remix that once again with size-specific column classes.
<div class="col-sm-3"> <div class="col-sm-3">
<label class="sr-only" for="inlineFormInputGroupUsername">Username</label> <label class="sr-only" for="inlineFormInputGroupUsername">Username</label>
<div class="input-group mb-2 mb-sm-0"> <div class="input-group mb-2 mb-sm-0">
<div class="input-group-addon">@</div> <div class="input-group-prepend">
<div class="input-group-text">@</div>
</div>
<input type="text" class="form-control" id="inlineFormInputGroupUsername" placeholder="Username"> <input type="text" class="form-control" id="inlineFormInputGroupUsername" placeholder="Username">
</div> </div>
</div> </div>
@ -575,7 +579,9 @@ You may need to manually address the width and alignment of individual form cont
<label class="sr-only" for="inlineFormInputGroupUsername2">Username</label> <label class="sr-only" for="inlineFormInputGroupUsername2">Username</label>
<div class="input-group mb-2 mr-sm-2"> <div class="input-group mb-2 mr-sm-2">
<div class="input-group-addon">@</div> <div class="input-group-prepend">
<div class="input-group-text">@</div>
</div>
<input type="text" class="form-control" id="inlineFormInputGroupUsername2" placeholder="Username"> <input type="text" class="form-control" id="inlineFormInputGroupUsername2" placeholder="Username">
</div> </div>
@ -725,17 +731,29 @@ When attempting to submit, you'll see the `:invalid` and `:valid` styles applied
{% example html %} {% example html %}
<form id="needs-validation" novalidate> <form id="needs-validation" novalidate>
<div class="row"> <div class="form-row">
<div class="col-md-6 mb-3"> <div class="col-md-4 mb-3">
<label for="validationCustom01">First name</label> <label for="validationCustom01">First name</label>
<input type="text" class="form-control" id="validationCustom01" placeholder="First name" value="Mark" required> <input type="text" class="form-control" id="validationCustom01" placeholder="First name" value="Mark" required>
</div> </div>
<div class="col-md-6 mb-3"> <div class="col-md-4 mb-3">
<label for="validationCustom02">Last name</label> <label for="validationCustom02">Last name</label>
<input type="text" class="form-control" id="validationCustom02" placeholder="Last name" value="Otto" required> <input type="text" class="form-control" id="validationCustom02" placeholder="Last name" value="Otto" required>
</div> </div>
<div class="col-md-4 mb-3">
<label for="validationCustomUsername">Username</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroupPrepend">@</span>
</div> </div>
<div class="row"> <input type="text" class="form-control" id="validationCustomUsername" placeholder="Username" aria-describedby="inputGroupPrepend" required>
<div class="invalid-feedback">
Please choose a username.
</div>
</div>
</div>
</div>
<div class="form-row">
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label for="validationCustom03">City</label> <label for="validationCustom03">City</label>
<input type="text" class="form-control" id="validationCustom03" placeholder="City" required> <input type="text" class="form-control" id="validationCustom03" placeholder="City" required>
@ -788,40 +806,39 @@ While these feedback styles cannot be styled with CSS, you can still customize t
{% example html %} {% example html %}
<form> <form>
<div class="row"> <div class="form-row">
<div class="col-md-6 mb-3"> <div class="col-md-4 mb-3">
<label for="validationDefault01">First name</label> <label for="validationDefault01">First name</label>
<input type="text" class="form-control" id="validationDefault01" placeholder="First name" value="Mark" required> <input type="text" class="form-control" id="validationDefault01" placeholder="First name" value="Mark" required>
</div> </div>
<div class="col-md-6 mb-3"> <div class="col-md-4 mb-3">
<label for="validationDefault02">Last name</label> <label for="validationDefault02">Last name</label>
<input type="text" class="form-control" id="validationDefault02" placeholder="Last name" value="Otto" required> <input type="text" class="form-control" id="validationDefault02" placeholder="Last name" value="Otto" required>
</div> </div>
<div class="col-md-4 mb-3">
<label for="validationDefaultUsername">Username</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroupPrepend2">@</span>
</div> </div>
<div class="row"> <input type="text" class="form-control" id="validationDefaultUsername" placeholder="Username" aria-describedby="inputGroupPrepend2" required>
</div>
</div>
</div>
<div class="form-row">
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label for="validationDefault03">City</label> <label for="validationDefault03">City</label>
<input type="text" class="form-control" id="validationDefault03" placeholder="City" required> <input type="text" class="form-control" id="validationDefault03" placeholder="City" required>
<div class="invalid-feedback">
Please provide a valid city.
</div>
</div> </div>
<div class="col-md-3 mb-3"> <div class="col-md-3 mb-3">
<label for="validationDefault04">State</label> <label for="validationDefault04">State</label>
<input type="text" class="form-control" id="validationDefault04" placeholder="State" required> <input type="text" class="form-control" id="validationDefault04" placeholder="State" required>
<div class="invalid-feedback">
Please provide a valid state.
</div>
</div> </div>
<div class="col-md-3 mb-3"> <div class="col-md-3 mb-3">
<label for="validationDefault05">Zip</label> <label for="validationDefault05">Zip</label>
<input type="text" class="form-control" id="validationDefault05" placeholder="Zip" required> <input type="text" class="form-control" id="validationDefault05" placeholder="Zip" required>
<div class="invalid-feedback">
Please provide a valid zip.
</div> </div>
</div> </div>
</div>
<button class="btn btn-primary" type="submit">Submit form</button> <button class="btn btn-primary" type="submit">Submit form</button>
</form> </form>
{% endexample %} {% endexample %}
@ -832,17 +849,29 @@ We recommend using client side validation, but in case you require server side,
{% example html %} {% example html %}
<form> <form>
<div class="row"> <div class="form-row">
<div class="col-md-6 mb-3"> <div class="col-md-4 mb-3">
<label for="validationServer01">First name</label> <label for="validationServer01">First name</label>
<input type="text" class="form-control is-valid" id="validationServer01" placeholder="First name" value="Mark" required> <input type="text" class="form-control is-valid" id="validationServer01" placeholder="First name" value="Mark" required>
</div> </div>
<div class="col-md-6 mb-3"> <div class="col-md-4 mb-3">
<label for="validationServer02">Last name</label> <label for="validationServer02">Last name</label>
<input type="text" class="form-control is-valid" id="validationServer02" placeholder="Last name" value="Otto" required> <input type="text" class="form-control is-valid" id="validationServer02" placeholder="Last name" value="Otto" required>
</div> </div>
<div class="col-md-4 mb-3">
<label for="validationServerUsername">Username</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroupPrepend3">@</span>
</div> </div>
<div class="row"> <input type="text" class="form-control is-invalid" id="validationServerUsername" placeholder="Username" aria-describedby="inputGroupPrepend3" required>
<div class="invalid-feedback">
Please choose a username.
</div>
</div>
</div>
</div>
<div class="form-row">
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label for="validationServer03">City</label> <label for="validationServer03">City</label>
<input type="text" class="form-control is-invalid" id="validationServer03" placeholder="City" required> <input type="text" class="form-control is-invalid" id="validationServer03" placeholder="City" required>

View File

@ -11,32 +11,36 @@ toc: true
Place one add-on or button on either side of an input. You may also place one on both sides of an input. **We do not support multiple form-controls in a single input group** and `<label>`s must come outside the input group. Place one add-on or button on either side of an input. You may also place one on both sides of an input. **We do not support multiple form-controls in a single input group** and `<label>`s must come outside the input group.
{% example html %} {% example html %}
<div class="input-group"> <div class="input-group mb-3">
<span class="input-group-addon" id="basic-addon1">@</span> <div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1">@</span>
</div>
<input type="text" class="form-control" placeholder="Username" aria-label="Username" aria-describedby="basic-addon1"> <input type="text" class="form-control" placeholder="Username" aria-label="Username" aria-describedby="basic-addon1">
</div> </div>
<br>
<div class="input-group"> <div class="input-group mb-3">
<input type="text" class="form-control" placeholder="Recipient's username" aria-label="Recipient's username" aria-describedby="basic-addon2"> <input type="text" class="form-control" placeholder="Recipient's username" aria-label="Recipient's username" aria-describedby="basic-addon2">
<span class="input-group-addon" id="basic-addon2">@example.com</span> <div class="input-group-append">
<span class="input-group-text" id="basic-addon2">@example.com</span>
</div>
</div> </div>
<br>
<label for="basic-url">Your vanity URL</label> <label for="basic-url">Your vanity URL</label>
<div class="input-group"> <div class="input-group mb-3">
<span class="input-group-addon" id="basic-addon3">https://example.com/users/</span> <div class="input-group-prepend">
<span class="input-group-text" id="basic-addon3">https://example.com/users/</span>
</div>
<input type="text" class="form-control" id="basic-url" aria-describedby="basic-addon3"> <input type="text" class="form-control" id="basic-url" aria-describedby="basic-addon3">
</div> </div>
<br>
<div class="input-group"> <div class="input-group mb-3">
<span class="input-group-addon">$</span> <div class="input-group-prepend">
<input type="text" class="form-control" aria-label="Amount (to the nearest dollar)"> <span class="input-group-text">$</span>
<span class="input-group-addon">.00</span> </div>
</div>
<br>
<div class="input-group">
<span class="input-group-addon">$</span>
<span class="input-group-addon">0.00</span>
<input type="text" class="form-control" aria-label="Amount (to the nearest dollar)"> <input type="text" class="form-control" aria-label="Amount (to the nearest dollar)">
<div class="input-group-append">
<span class="input-group-text">.00</span>
</div>
</div> </div>
{% endexample %} {% endexample %}
@ -44,40 +48,66 @@ Place one add-on or button on either side of an input. You may also place one on
Add the relative form sizing classes to the `.input-group` itself and contents within will automatically resize—no need for repeating the form control size classes on each element. Add the relative form sizing classes to the `.input-group` itself and contents within will automatically resize—no need for repeating the form control size classes on each element.
**Sizing on the individual input group elements isn't supported.**
{% example html %} {% example html %}
<div class="input-group input-group-lg"> <div class="input-group input-group-sm mb-3">
<span class="input-group-addon" id="sizing-addon1">@</span> <div class="input-group-prepend">
<input type="text" class="form-control" placeholder="Username" aria-label="Username" aria-describedby="sizing-addon1"> <span class="input-group-text" id="inputGroup-sizing-sm">Small</span>
</div>
<input type="text" class="form-control" aria-label="Small" aria-describedby="inputGroup-sizing-sm">
</div> </div>
<br>
<div class="input-group input-group-sm"> <div class="input-group mb-3">
<span class="input-group-addon" id="sizing-addon2">@</span> <div class="input-group-prepend">
<input type="text" class="form-control" placeholder="Username" aria-label="Username" aria-describedby="sizing-addon2"> <span class="input-group-text" id="inputGroup-sizing-default">Default</span>
</div>
<input type="text" class="form-control" aria-label="Default" aria-describedby="inputGroup-sizing-default">
</div>
<div class="input-group input-group-lg">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroup-sizing-lg">Large</span>
</div>
<input type="text" class="form-control" aria-label="Large" aria-describedby="inputGroup-sizing-sm">
</div> </div>
{% endexample %} {% endexample %}
## Checkboxes and radio addons ## Checkboxes and radios
Place any checkbox or radio option within an input group's addon instead of text. Place any checkbox or radio option within an input group's addon instead of text.
{% example html %} {% example html %}
<div class="row"> <div class="input-group mb-3">
<div class="col-lg-6"> <div class="input-group-prepend">
<div class="input-group"> <div class="input-group-text">
<span class="input-group-addon">
<input type="checkbox" aria-label="Checkbox for following text input"> <input type="checkbox" aria-label="Checkbox for following text input">
</span> </div>
</div>
<input type="text" class="form-control" aria-label="Text input with checkbox"> <input type="text" class="form-control" aria-label="Text input with checkbox">
</div> </div>
</div>
<div class="col-lg-6"> <div class="input-group">
<div class="input-group"> <div class="input-group-prepend">
<span class="input-group-addon"> <div class="input-group-text">
<input type="radio" aria-label="Radio button for following text input"> <input type="radio" aria-label="Radio button for following text input">
</span> </div>
</div>
<input type="text" class="form-control" aria-label="Text input with radio button"> <input type="text" class="form-control" aria-label="Text input with radio button">
</div>
{% endexample %}
## Multiple inputs
While multiple `<input>`s are supported visually, validation styles are only available for input groups with a single `<input>`.
{% example html %}
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="">First and last name</span>
</div> </div>
</div> <input type="text" class="form-control">
<input type="text" class="form-control">
</div> </div>
{% endexample %} {% endexample %}
@ -86,61 +116,53 @@ Place any checkbox or radio option within an input group's addon instead of text
Multiple add-ons are supported and can be mixed with checkbox and radio input versions. Multiple add-ons are supported and can be mixed with checkbox and radio input versions.
{% example html %} {% example html %}
<div class="row"> <div class="input-group mb-3">
<div class="col-lg-6"> <div class="input-group-prepend">
<div class="input-group"> <span class="input-group-text">$</span>
<span class="input-group-addon"> <span class="input-group-text">0.00</span>
<input type="checkbox" aria-label="Checkbox for following text input">
</span>
<span class="input-group-addon">$</span>
<input type="text" class="form-control" aria-label="Text input with checkbox">
</div>
</div>
<div class="col-lg-6">
<div class="input-group">
<span class="input-group-addon">$</span>
<span class="input-group-addon">0.00</span>
<input type="text" class="form-control" aria-label="Text input with radio button">
</div> </div>
<input type="text" class="form-control" aria-label="Amount (to the nearest dollar)">
</div>
<div class="input-group">
<input type="text" class="form-control" aria-label="Amount (to the nearest dollar)">
<div class="input-group-append">
<span class="input-group-text">$</span>
<span class="input-group-text">0.00</span>
</div> </div>
</div> </div>
{% endexample %} {% endexample %}
## Button addons ## Button addons
Buttons in input groups must wrapped in a `.input-group-btn` for proper alignment and sizing. This is required due to default browser styles that cannot be overridden.
{% example html %} {% example html %}
<div class="row"> <div class="input-group mb-3">
<div class="col-lg-6"> <div class="input-group-prepend">
<div class="input-group"> <button class="btn btn-outline-secondary" type="button">Button</button>
<span class="input-group-btn">
<button class="btn btn-secondary" type="button">Go!</button>
</span>
<input type="text" class="form-control" placeholder="Search for..." aria-label="Search for...">
</div>
</div>
<div class="col-lg-6">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search for..." aria-label="Search for...">
<span class="input-group-btn">
<button class="btn btn-secondary" type="button">Go!</button>
</span>
</div> </div>
<input type="text" class="form-control" placeholder="" aria-label="" aria-describedby="basic-addon1">
</div>
<div class="input-group mb-3">
<input type="text" class="form-control" placeholder="Recipient's username" aria-label="Recipient's username" aria-describedby="basic-addon2">
<div class="input-group-append">
<button class="btn btn-outline-secondary" type="button">Button</button>
</div> </div>
</div> </div>
<br>
<div class="row"> <div class="input-group mb-3">
<div class="col-lg-6 offset-lg-3"> <div class="input-group-prepend">
<div class="input-group"> <button class="btn btn-outline-secondary" type="button">Button</button>
<span class="input-group-btn"> <button class="btn btn-outline-secondary" type="button">Button</button>
<button class="btn btn-secondary" type="button">Hate it</button>
</span>
<input type="text" class="form-control" placeholder="Product name" aria-label="Product name">
<span class="input-group-btn">
<button class="btn btn-secondary" type="button">Love it</button>
</span>
</div> </div>
<input type="text" class="form-control" placeholder="" aria-label="" aria-describedby="basic-addon1">
</div>
<div class="input-group">
<input type="text" class="form-control" placeholder="Recipient's username" aria-label="Recipient's username" aria-describedby="basic-addon2">
<div class="input-group-append">
<button class="btn btn-outline-secondary" type="button">Button</button>
<button class="btn btn-outline-secondary" type="button">Button</button>
</div> </div>
</div> </div>
{% endexample %} {% endexample %}
@ -148,13 +170,9 @@ Buttons in input groups must wrapped in a `.input-group-btn` for proper alignmen
## Buttons with dropdowns ## Buttons with dropdowns
{% example html %} {% example html %}
<div class="row"> <div class="input-group mb-3">
<div class="col-lg-6"> <div class="input-group-prepend">
<div class="input-group"> <button class="btn btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</button>
<div class="input-group-btn">
<button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Action
</button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a> <a class="dropdown-item" href="#">Another action</a>
@ -164,16 +182,13 @@ Buttons in input groups must wrapped in a `.input-group-btn` for proper alignmen
</div> </div>
</div> </div>
<input type="text" class="form-control" aria-label="Text input with dropdown button"> <input type="text" class="form-control" aria-label="Text input with dropdown button">
</div> </div>
</div>
<div class="col-lg-6"> <div class="input-group">
<div class="input-group">
<input type="text" class="form-control" aria-label="Text input with dropdown button"> <input type="text" class="form-control" aria-label="Text input with dropdown button">
<div class="input-group-btn"> <div class="input-group-append">
<button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <button class="btn btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</button>
Action <div class="dropdown-menu">
</button>
<div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a> <a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a> <a class="dropdown-item" href="#">Something else here</a>
@ -181,20 +196,16 @@ Buttons in input groups must wrapped in a `.input-group-btn` for proper alignmen
<a class="dropdown-item" href="#">Separated link</a> <a class="dropdown-item" href="#">Separated link</a>
</div> </div>
</div> </div>
</div>
</div>
</div> </div>
{% endexample %} {% endexample %}
## Segmented buttons ## Segmented buttons
{% example html %} {% example html %}
<div class="row"> <div class="input-group mb-3">
<div class="col-lg-6"> <div class="input-group-prepend">
<div class="input-group"> <button type="button" class="btn btn-outline-secondary">Action</button>
<div class="input-group-btn"> <button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<button type="button" class="btn btn-secondary">Action</button>
<button type="button" class="btn btn-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="sr-only">Toggle Dropdown</span> <span class="sr-only">Toggle Dropdown</span>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
@ -205,18 +216,17 @@ Buttons in input groups must wrapped in a `.input-group-btn` for proper alignmen
<a class="dropdown-item" href="#">Separated link</a> <a class="dropdown-item" href="#">Separated link</a>
</div> </div>
</div> </div>
<input type="text" class="form-control" aria-label="Text input with segmented button dropdown"> <input type="text" class="form-control" aria-label="Text input with segmented dropdown button">
</div> </div>
</div>
<div class="col-lg-6"> <div class="input-group">
<div class="input-group"> <input type="text" class="form-control" aria-label="Text input with segmented dropdown button">
<input type="text" class="form-control" aria-label="Text input with segmented button dropdown"> <div class="input-group-append">
<div class="input-group-btn"> <button type="button" class="btn btn-outline-secondary">Action</button>
<button type="button" class="btn btn-secondary">Action</button> <button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<button type="button" class="btn btn-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="sr-only">Toggle Dropdown</span> <span class="sr-only">Toggle Dropdown</span>
</button> </button>
<div class="dropdown-menu dropdown-menu-right"> <div class="dropdown-menu">
<a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a> <a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a> <a class="dropdown-item" href="#">Something else here</a>
@ -224,8 +234,6 @@ Buttons in input groups must wrapped in a `.input-group-btn` for proper alignmen
<a class="dropdown-item" href="#">Separated link</a> <a class="dropdown-item" href="#">Separated link</a>
</div> </div>
</div> </div>
</div>
</div>
</div> </div>
{% endexample %} {% endexample %}
@ -237,7 +245,9 @@ Input groups include support for custom selects and custom file inputs. Browser
{% example html %} {% example html %}
<div class="input-group mb-3"> <div class="input-group mb-3">
<label class="input-group-addon" for="inputGroupSelect01">Options</label> <div class="input-group-prepend">
<label class="input-group-text" for="inputGroupSelect01">Options</label>
</div>
<select class="custom-select" id="inputGroupSelect01"> <select class="custom-select" id="inputGroupSelect01">
<option selected>Choose...</option> <option selected>Choose...</option>
<option value="1">One</option> <option value="1">One</option>
@ -253,13 +263,15 @@ Input groups include support for custom selects and custom file inputs. Browser
<option value="2">Two</option> <option value="2">Two</option>
<option value="3">Three</option> <option value="3">Three</option>
</select> </select>
<label class="input-group-addon" for="inputGroupSelect02">Options</label> <div class="input-group-append">
<label class="input-group-text" for="inputGroupSelect02">Options</label>
</div>
</div> </div>
<div class="input-group mb-3"> <div class="input-group mb-3">
<span class="input-group-btn"> <div class="input-group-prepend">
<button class="btn btn-secondary" type="button">Button</button> <button class="btn btn-outline-secondary" type="button">Button</button>
</span> </div>
<select class="custom-select" id="inputGroupSelect03"> <select class="custom-select" id="inputGroupSelect03">
<option selected>Choose...</option> <option selected>Choose...</option>
<option value="1">One</option> <option value="1">One</option>
@ -275,9 +287,9 @@ Input groups include support for custom selects and custom file inputs. Browser
<option value="2">Two</option> <option value="2">Two</option>
<option value="3">Three</option> <option value="3">Three</option>
</select> </select>
<span class="input-group-btn"> <div class="input-group-append">
<button class="btn btn-secondary" type="button">Button</button> <button class="btn btn-outline-secondary" type="button">Button</button>
</span> </div>
</div> </div>
{% endexample %} {% endexample %}
@ -285,7 +297,9 @@ Input groups include support for custom selects and custom file inputs. Browser
{% example html %} {% example html %}
<div class="input-group mb-3"> <div class="input-group mb-3">
<span class="input-group-addon">Upload</span> <div class="input-group-prepend">
<span class="input-group-text">Upload</span>
</div>
<label class="custom-file"> <label class="custom-file">
<input type="file" id="inputGroupFile01" class="custom-file-input" required> <input type="file" id="inputGroupFile01" class="custom-file-input" required>
<span class="custom-file-control"></span> <span class="custom-file-control"></span>
@ -297,13 +311,15 @@ Input groups include support for custom selects and custom file inputs. Browser
<input type="file" id="inputGroupFile02" class="custom-file-input" required> <input type="file" id="inputGroupFile02" class="custom-file-input" required>
<span class="custom-file-control"></span> <span class="custom-file-control"></span>
</label> </label>
<span class="input-group-addon" id="">Upload</span> <div class="input-group-append">
<span class="input-group-text" id="">Upload</span>
</div>
</div> </div>
<div class="input-group mb-3"> <div class="input-group mb-3">
<span class="input-group-btn"> <div class="input-group-prepend">
<button class="btn btn-secondary" type="button">Button</button> <button class="btn btn-outline-secondary" type="button">Button</button>
</span> </div>
<label class="custom-file"> <label class="custom-file">
<input type="file" id="inputGroupFile03" class="custom-file-input" required> <input type="file" id="inputGroupFile03" class="custom-file-input" required>
<span class="custom-file-control"></span> <span class="custom-file-control"></span>
@ -315,9 +331,9 @@ Input groups include support for custom selects and custom file inputs. Browser
<input type="file" id="inputGroupFile04" class="custom-file-input" required> <input type="file" id="inputGroupFile04" class="custom-file-input" required>
<span class="custom-file-control"></span> <span class="custom-file-control"></span>
</label> </label>
<span class="input-group-btn"> <div class="input-group-append">
<button class="btn btn-secondary" type="button">Button</button> <button class="btn btn-outline-secondary" type="button">Button</button>
</span> </div>
</div> </div>
{% endexample %} {% endexample %}

View File

@ -224,7 +224,9 @@ Input groups work, too:
<nav class="navbar navbar-light bg-light"> <nav class="navbar navbar-light bg-light">
<form class="form-inline"> <form class="form-inline">
<div class="input-group"> <div class="input-group">
<span class="input-group-addon" id="basic-addon1">@</span> <div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1">@</span>
</div>
<input type="text" class="form-control" placeholder="Username" aria-label="Username" aria-describedby="basic-addon1"> <input type="text" class="form-control" placeholder="Username" aria-label="Username" aria-describedby="basic-addon1">
</div> </div>
</form> </form>

View File

@ -16,6 +16,16 @@ While Beta 2 saw the bulk of our breaking changes during the beta phase, but we
- Updated selector for input-based button groups. Instead of `[data-toggle="buttons"] { }` for style and behavior, we use the `data` attribute just for JS behaviors and rely on a new `.btn-group-toggle` class for styling. - Updated selector for input-based button groups. Instead of `[data-toggle="buttons"] { }` for style and behavior, we use the `data` attribute just for JS behaviors and rely on a new `.btn-group-toggle` class for styling.
- Removed `.col-form-legend` in favor of a slightly improved `.col-form-label`. This way `.col-form-label-sm` and `.col-form-label-lg` can be used on `<legend>` elements with ease. - Removed `.col-form-legend` in favor of a slightly improved `.col-form-label`. This way `.col-form-label-sm` and `.col-form-label-lg` can be used on `<legend>` elements with ease.
### Input groups
- Input group addons are now specific to their placement relative to an input. We've dropped `.input-group-addon` and `.input-group-btn` for two new classes, `.input-group-prepend` and `.input-group-append`. You must explicitly use an append or a prepend now, simplifying much of our CSS.
- Validation styles are now supported, as are multiple inputs (though you can only validate one input per group).
- Sizing classes must be on the parent `.input-group` and not the individual form elements.
- Due to limitations in how CSS selectors work, all buttons must be the same element (e.g., `<a>` or `<button>`).
## Beta 2 changes ## Beta 2 changes
While in beta, we aim to have no breaking changes. However, things don't always go as planned. Below are the breaking changes to bear in mind when moving from Beta 1 to Beta 2. While in beta, we aim to have no breaking changes. However, things don't always go as planned. Below are the breaking changes to bear in mind when moving from Beta 1 to Beta 2.

View File

@ -7,77 +7,87 @@
.input-group { .input-group {
position: relative; position: relative;
display: flex; display: flex;
flex-wrap: wrap; // For form validation feedback
align-items: stretch; align-items: stretch;
width: 100%; width: 100%;
.form-control { .form-control,
// Ensure that the input is always above the *appended* addon button for .custom-select,
// proper border colors. .custom-file {
position: relative; position: relative; // For focus state's z-index
z-index: 1;
flex: 1 1 auto; flex: 1 1 auto;
// Add width 1% and flex-basis auto to ensure that button will not wrap out // Add width 1% and flex-basis auto to ensure that button will not wrap out
// the column. Applies to IE Edge+ and Firefox. Chrome does not require this. // the column. Applies to IE Edge+ and Firefox. Chrome does not require this.
width: 1%; width: 1%;
margin-bottom: 0; margin-bottom: 0;
// Bring the "active" form control to the front // Bring the "active" form control to the top of surrounding elements
@include hover-focus-active { &:focus {
z-index: 3;
}
+ .form-control {
margin-left: -$input-border-width;
}
}
.form-control,
.custom-select {
&:not(:first-child):not(:last-of-type) { @include border-radius(0); }
&:first-child { @include border-right-radius(0); }
&:last-of-type:not(:first-child) { @include border-left-radius(0); }
}
// Custom file inputs have more complex markup, thus requiring different
// border-radius overrides.
.custom-file {
&:not(:first-child):not(:last-of-type) .custom-file-control,
&:not(:first-child):not(:last-of-type) .custom-file-control::before { @include border-radius(0); }
&:first-child .custom-file-control,
&:first-child .custom-file-control::before { @include border-right-radius(0); }
&:last-of-type:not(:first-child) .custom-file-control,
&:last-of-type:not(:first-child) .custom-file-control::before { @include border-left-radius(0); }
}
}
// Prepend and append
//
// While it requires one extra layer of HTML for each, dedicated prepend and
// append elements allow us to 1) be less clever, 2) simplify our selectors, and
// 3) support HTML5 form validation.
.input-group-prepend,
.input-group-append {
display: flex;
align-items: center;
// Ensure buttons are always above inputs for more visually pleasing borders.
// This isn't needed for `.input-group-text` since it shares the same border-color
// as our inputs.
.btn {
position: relative;
z-index: 2; z-index: 2;
} }
.btn + .btn,
.btn + .input-group-text,
.input-group-text + .input-group-text,
.input-group-text + .btn {
margin-left: -$input-border-width;
} }
} }
.input-group-addon, .input-group-prepend { margin-right: -$input-border-width; }
.input-group-btn, .input-group-append { margin-left: -$input-border-width; }
.input-group .form-control,
.input-group .custom-select,
.input-group .custom-file {
display: flex;
align-items: center;
&:not(:first-child):not(:last-child) {
@include border-radius(0);
}
}
.input-group .custom-file { // Textual addons
display: flex;
align-items: center;
}
.input-group .custom-select,
.input-group .custom-file {
width: 100%;
}
.input-group-addon,
.input-group-btn {
white-space: nowrap;
}
// Sizing options
// //
// Remix the default form control sizing classes into new ones for easier // Serves as a catch-all element for any text or radio/checkbox input you wish
// manipulation. // to prepend or append to an input.
.input-group-lg > .form-control, .input-group-text {
.input-group-lg > .input-group-addon,
.input-group-lg > .input-group-btn > .btn {
@extend .form-control-lg;
}
.input-group-sm > .form-control,
.input-group-sm > .input-group-addon,
.input-group-sm > .input-group-btn > .btn {
@extend .form-control-sm;
}
//
// Text input groups
//
.input-group-addon {
padding: $input-padding-y $input-padding-x; padding: $input-padding-y $input-padding-x;
margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom
font-size: $font-size-base; // Match inputs font-size: $font-size-base; // Match inputs
@ -85,23 +95,11 @@
line-height: $input-line-height; line-height: $input-line-height;
color: $input-group-addon-color; color: $input-group-addon-color;
text-align: center; text-align: center;
white-space: nowrap;
background-color: $input-group-addon-bg; background-color: $input-group-addon-bg;
border: $input-border-width solid $input-group-addon-border-color; border: $input-border-width solid $input-group-addon-border-color;
@include border-radius($input-border-radius); @include border-radius($input-border-radius);
// Sizing
&.form-control-sm {
padding: $input-padding-y-sm $input-padding-x-sm;
font-size: $font-size-sm;
@include border-radius($input-border-radius-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);
}
// Nuke default margins from checkboxes and radios to vertically center within. // Nuke default margins from checkboxes and radios to vertically center within.
input[type="radio"], input[type="radio"],
input[type="checkbox"] { input[type="checkbox"] {
@ -110,100 +108,56 @@
} }
// Sizing
// //
// Reset rounded corners // Remix the default form control sizing classes into new ones for easier
// // manipulation.
.input-group .form-control:not(:last-child), .input-group-lg > .form-control,
.input-group .custom-select:not(:last-child), .input-group-lg > .input-group-prepend > .input-group-text,
.input-group .custom-file:not(:last-child) .custom-file-control::before, .input-group-lg > .input-group-append > .input-group-text,
.input-group-addon:not(:last-child), .input-group-lg > .input-group-prepend > .btn,
.input-group-btn:not(:last-child) > .btn, .input-group-lg > .input-group-append > .btn {
.input-group-btn:not(:last-child) > .btn-group > .btn, @extend .form-control-lg;
.input-group-btn:not(:last-child) > .dropdown-toggle, }
.input-group-btn:not(:first-child) > .btn:not(:last-child):not(.dropdown-toggle),
.input-group-btn:not(:first-child) > .btn-group:not(:last-child) > .btn { .input-group-sm > .form-control,
.input-group-sm > .input-group-prepend > .input-group-text,
.input-group-sm > .input-group-append > .input-group-text,
.input-group-sm > .input-group-prepend > .btn,
.input-group-sm > .input-group-append > .btn {
@extend .form-control-sm;
}
// Prepend and append rounded corners
//
// These rulesets must come after the sizing ones to properly override sm and lg
// border-radius values when extending. They're more specific than we'd like
// with the `.input-group >` part, but without it, we cannot override the sizing.
.input-group > .input-group-prepend > .btn,
.input-group > .input-group-prepend > .input-group-text {
// All prepended buttons have no right border-radius
@include border-right-radius(0); @include border-right-radius(0);
}
.input-group-addon:not(:last-child) { + .btn,
border-right: 0; + .input-group-text {
}
.input-group .form-control:not(:first-child),
.input-group .custom-select:not(:first-child),
.input-group .custom-file:not(:first-child) .custom-file-control,
.input-group-addon:not(:first-child),
.input-group-btn:not(:first-child) > .btn,
.input-group-btn:not(:first-child) > .btn-group > .btn,
.input-group-btn:not(:first-child) > .dropdown-toggle,
.input-group-btn:not(:last-child) > .btn:not(:first-child),
.input-group-btn:not(:last-child) > .btn-group:not(:first-child) > .btn {
@include border-left-radius(0); @include border-left-radius(0);
}
.form-control,
.custom-select,
.custom-file {
+ .input-group-addon:not(:first-child) {
border-left: 0;
} }
} }
// // We separate out the button and input resets here because `.input-group-text`
// Button input groups // can be any HTML element, but buttons are always inputs, buttons, or anchors.
// .input-group > .input-group-append {
// Everything but the last one have no rounded corners
.input-group-btn { .btn:not(:last-of-type),
position: relative; .input-group-text:not(:last-child) {
align-items: stretch; @include border-radius(0);
// Jankily prevent input button groups from wrapping with `white-space` and
// `font-size` in combination with `inline-block` on buttons.
font-size: 0;
white-space: nowrap;
// Negative margin for spacing, position for bringing hovered/focused/actived
// element above the siblings.
> .btn {
position: relative;
+ .btn {
margin-left: (-$input-border-width);
} }
// Bring the "active" button to the front .btn:last-of-type,
@include hover-focus-active { .input-group-text:last-child {
z-index: 2; @include border-left-radius(0);
}
}
&:first-child > .btn + .btn {
margin-left: 0;
}
// Negative margin to only have a single, shared border between the two
&:not(:last-child) {
> .btn,
> .btn-group {
margin-right: (-$input-border-width);
}
}
&:not(:first-child) {
> .btn,
> .btn-group {
z-index: 1;
// remove nagative margin ($input-border-width) to solve overlapping issue with button.
margin-left: 0;
// When input is first, overlap the right side of it with the button(-group)
&:first-child {
margin-left: (-$input-border-width);
}
// Because specificity
@include hover-focus-active {
z-index: 2;
}
}
} }
} }

View File

@ -30,6 +30,7 @@
.#{$state}-feedback { .#{$state}-feedback {
display: none; display: none;
width: 100%;
margin-top: $form-feedback-margin-top; margin-top: $form-feedback-margin-top;
font-size: $form-feedback-font-size; font-size: $form-feedback-font-size;
color: $color; color: $color;