Add new form feedback states, clean up existing form styles

New stuff:

* Adds `.has-feedback` and `.form-control-feedback` to show icon-based
form feedback to users. Fixes #11836.
* Removes the `width: 1em` on `.glyphicon` because it makes it
impractical to resize the width of all icons, even if they’re not
“empty” (e.g., a simple `.glyphicon { width: 30px; }` wouldn’t work,
nor would a class preceeded by a parent class.

Clean up:

* Sets `width: auto;` on all `.form-control`s within inline forms.
* Removes all the inline `select` menu `width` styles because all
inputs are now `auto`.
* Update form states docs to separate out sections better.
This commit is contained in:
Mark Otto 2013-12-15 17:15:09 -08:00
parent d9345ff7d5
commit 2979e4bcea
7 changed files with 184 additions and 37 deletions

View File

@ -66,7 +66,9 @@
<li><a href="#forms-horizontal">Horizontal form</a></li>
<li><a href="#forms-controls">Supported controls</a></li>
<li><a href="#forms-controls-static">Static control</a></li>
<li><a href="#forms-control-states">Control states</a></li>
<li><a href="#forms-control-focus">Focus state</a></li>
<li><a href="#forms-control-disabled">Disabled state</a></li>
<li><a href="#forms-control-validation">Validation states</a></li>
<li><a href="#forms-control-sizes">Control sizing</a></li>
<li><a href="#forms-help-text">Help text</a></li>
</ul>

View File

@ -1877,10 +1877,7 @@ For example, <code>&lt;section&gt;</code> should be wrapped as inline.
{% endhighlight %}
<h2 id="forms-control-states">Form states</h2>
<p>Provide feedback to users or visitors with basic feedback states on form controls and labels.</p>
<h3 id="forms-input-focus">Input focus</h3>
<h2 id="forms-control-focus">Input focus</h2>
<p>We remove the default <code>outline</code> styles on some form controls and apply a <code>box-shadow</code> in its place for <code>:focus</code>.</p>
<div class="bs-example">
<form role="form">
@ -1891,7 +1888,8 @@ For example, <code>&lt;section&gt;</code> should be wrapped as inline.
<input class="form-control" id="focusedInput" type="text" value="This is focused...">
{% endhighlight %}
<h3 id="forms-disabled-inputs">Disabled inputs</h3>
<h2 id="forms-control-disabled">Disabled inputs</h2>
<p>Add the <code>disabled</code> attribute on an input to prevent user input and trigger a slightly different look.</p>
<div class="bs-example">
<form role="form">
@ -1960,7 +1958,8 @@ For example, <code>&lt;section&gt;</code> should be wrapped as inline.
</form>
{% endhighlight %}
<h3 id="forms-validation">Validation states</h3>
<h2 id="forms-control-validation">Validation states</h2>
<p>Bootstrap includes validation styles for error, warning, and success states on form controls. To use, add <code>.has-warning</code>, <code>.has-error</code>, or <code>.has-success</code> to the parent element. Any <code>.control-label</code>, <code>.form-control</code>, and <code>.help-block</code> within that element will receive the validation styles.</p>
<div class="bs-example">
@ -1994,6 +1993,89 @@ For example, <code>&lt;section&gt;</code> should be wrapped as inline.
</div>
{% endhighlight %}
<h3>With optional icons</h3>
<p>You can also add optional feedback icons with the addition of an extra class and the right icon.</p>
<div class="bs-example">
<form role="form">
<div class="form-group has-success has-feedback">
<label class="control-label" for="inputSuccess">Input with success</label>
<input type="text" class="form-control" id="inputSuccess">
<span class="glyphicon glyphicon-ok form-control-feedback"></span>
</div>
<div class="form-group has-warning has-feedback">
<label class="control-label" for="inputWarning">Input with warning</label>
<input type="text" class="form-control" id="inputWarning">
<span class="glyphicon glyphicon-warning-sign form-control-feedback"></span>
</div>
<div class="form-group has-error has-feedback">
<label class="control-label" for="inputError">Input with error</label>
<input type="text" class="form-control" id="inputError">
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
</div>
</form>
</div>
{% highlight html %}
<div class="form-group has-success has-feedback">
<label class="control-label" for="inputSuccess">Input with success</label>
<input type="text" class="form-control" id="inputSuccess">
<span class="glyphicon glyphicon-ok form-control-feedback"></span>
</div>
<div class="form-group has-warning has-feedback">
<label class="control-label" for="inputWarning">Input with warning</label>
<input type="text" class="form-control" id="inputWarning">
<span class="glyphicon glyphicon-warning-sign form-control-feedback"></span>
</div>
<div class="form-group has-error has-feedback">
<label class="control-label" for="inputError">Input with error</label>
<input type="text" class="form-control" id="inputError">
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
</div>
{% endhighlight %}
<p>Optional icons also work on horizontal and inline forms.</p>
<div class="bs-example">
<form class="form-horizontal" role="form">
<div class="form-group has-success has-feedback">
<label class="control-label col-sm-3" for="inputSuccess">Input with success</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="inputSuccess">
<span class="glyphicon glyphicon-ok form-control-feedback"></span>
</div>
</div>
</form>
</div>
{% highlight html %}
<form class="form-horizontal" role="form">
<div class="form-group has-success has-feedback">
<label class="control-label col-sm-3" for="inputSuccess">Input with success</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="inputSuccess">
<span class="glyphicon glyphicon-ok form-control-feedback"></span>
</div>
</div>
</form>
{% endhighlight %}
<div class="bs-example">
<form class="form-inline" role="form">
<div class="form-group has-success has-feedback">
<label class="control-label" for="inputSuccess">Input with success</label>
<input type="text" class="form-control" id="inputSuccess">
<span class="glyphicon glyphicon-ok form-control-feedback"></span>
</div>
</form>
</div>
{% highlight html %}
<form class="form-inline" role="form">
<div class="form-group has-success has-feedback">
<label class="control-label" for="inputSuccess">Input with success</label>
<input type="text" class="form-control" id="inputSuccess">
<span class="glyphicon glyphicon-ok form-control-feedback"></span>
</div>
</form>
{% endhighlight %}
<h2 id="forms-control-sizes">Control sizing</h2>
<p>Set heights using classes like <code>.input-lg</code>, and set widths using grid column classes like <code>.col-lg-*</code>.</p>

View File

@ -1783,6 +1783,22 @@ select.input-lg {
textarea.input-lg {
height: auto;
}
.has-feedback {
position: relative;
}
.has-feedback .form-control {
padding-right: 42.5px;
}
.has-feedback .form-control-feedback {
position: absolute;
top: 25px;
right: 0;
display: block;
width: 34px;
height: 34px;
line-height: 34px;
text-align: center;
}
.has-warning .help-block,
.has-warning .control-label,
.has-warning .radio,
@ -1806,6 +1822,9 @@ textarea.input-lg {
background-color: #fcf8e3;
border-color: #8a6d3b;
}
.has-warning .form-control-feedback {
color: #8a6d3b;
}
.has-error .help-block,
.has-error .control-label,
.has-error .radio,
@ -1829,6 +1848,9 @@ textarea.input-lg {
background-color: #f2dede;
border-color: #a94442;
}
.has-error .form-control-feedback {
color: #a94442;
}
.has-success .help-block,
.has-success .control-label,
.has-success .radio,
@ -1852,6 +1874,9 @@ textarea.input-lg {
background-color: #dff0d8;
border-color: #3c763d;
}
.has-success .form-control-feedback {
color: #3c763d;
}
.form-control-static {
margin-bottom: 0;
}
@ -1869,13 +1894,12 @@ textarea.input-lg {
}
.form-inline .form-control {
display: inline-block;
width: auto;
vertical-align: middle;
}
.form-inline select.form-control {
width: auto;
}
.form-inline > select.form-control {
width: auto;
.form-inline .control-label {
margin-bottom: 0;
vertical-align: middle;
}
.form-inline .radio,
.form-inline .checkbox {
@ -1890,6 +1914,9 @@ textarea.input-lg {
float: none;
margin-left: 0;
}
.form-inline .has-feedback .form-control-feedback {
top: 0;
}
}
.form-horizontal .control-label,
.form-horizontal .radio,
@ -1916,6 +1943,10 @@ textarea.input-lg {
text-align: right;
}
}
.form-horizontal .has-feedback .form-control-feedback {
top: 0;
right: 15px;
}
.btn {
display: inline-block;
padding: 6px 12px;
@ -2311,9 +2342,6 @@ input[type="button"].btn-block {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.glyphicon:empty {
width: 1em;
}
.glyphicon-asterisk:before {
content: "\2a";
}
@ -3783,13 +3811,12 @@ textarea.input-group-sm > .input-group-btn > .btn {
}
.navbar-form .form-control {
display: inline-block;
width: auto;
vertical-align: middle;
}
.navbar-form select.form-control {
width: auto;
}
.navbar-form > select.form-control {
width: auto;
.navbar-form .control-label {
margin-bottom: 0;
vertical-align: middle;
}
.navbar-form .radio,
.navbar-form .checkbox {
@ -3804,6 +3831,9 @@ textarea.input-group-sm > .input-group-btn > .btn {
float: none;
margin-left: 0;
}
.navbar-form .has-feedback .form-control-feedback {
top: 0;
}
}
@media (max-width: 767px) {
.navbar-form .form-group {

File diff suppressed because one or more lines are too long

View File

@ -253,15 +253,35 @@ input[type="checkbox"],
//
// Apply contextual and semantic states to individual form controls.
// Warning
.has-feedback {
// Enable absolute positioning
position: relative;
// Ensure icons don't overlap text
.form-control {
padding-right: (@input-height-base * 1.25);
}
// Feedback icon (requires .glyphicon classes)
.form-control-feedback {
position: absolute;
top: (@line-height-computed + 5); // Height of the `label` and it's margin
right: 0;
display: block;
width: @input-height-base;
height: @input-height-base;
line-height: @input-height-base;
text-align: center;
}
}
// Feedback states
.has-warning {
.form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);
}
// Error
.has-error {
.form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);
}
// Success
.has-success {
.form-control-validation(@state-success-text; @state-success-text; @state-success-bg);
}
@ -307,7 +327,7 @@ input[type="checkbox"],
// Kick in the inline
@media (min-width: @screen-sm) {
// Inline-block all the things for "inline"
.form-group {
.form-group {
display: inline-block;
margin-bottom: 0;
vertical-align: middle;
@ -316,17 +336,13 @@ input[type="checkbox"],
// In navbar-form, allow folks to *not* use `.form-group`
.form-control {
display: inline-block;
width: auto; // Prevent labels from stacking above inputs in `.form-group`
vertical-align: middle;
}
// Override `width: 100%;` when not within a `.form-group`
select.form-control {
width: auto;
}
// Override `width: 100%;` when not within a `.form-group`
> select.form-control {
width: auto;
.control-label {
margin-bottom: 0;
vertical-align: middle;
}
// Remove default margin on radios/checkboxes that were used for stacking, and
@ -345,6 +361,14 @@ input[type="checkbox"],
float: none;
margin-left: 0;
}
// Validation states
//
// Reposition the icon because it's now within a grid column and columns have
// `position: relative;` on them. Also accounts for the grid gutter padding.
.has-feedback .form-control-feedback {
top: 0;
}
}
}
@ -388,4 +412,13 @@ input[type="checkbox"],
text-align: right;
}
}
// Validation states
//
// Reposition the icon because it's now within a grid column and columns have
// `position: relative;` on them. Also accounts for the grid gutter padding.
.has-feedback .form-control-feedback {
top: 0;
right: (@grid-gutter-width / 2);
}
}

View File

@ -28,10 +28,6 @@
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
&:empty {
width: 1em;
}
}
// Individual icons

View File

@ -851,6 +851,10 @@
border-color: @border-color;
background-color: @background-color;
}
// Optional feedack icon
.form-control-feedback {
color: @text-color;
}
}
// Form control focus state