Form Control States

Beyond layout, a form field can communicate its own state: focused, disabled, read-only, or carrying a validation result. The first three are plain HTML/CSS behaviors Bootstrap styles for you automatically; validation states are classes you add yourself, usually from server-side or JavaScript form-checking logic.

1. Focus State: :focus

No class needed — every .form-control already ships with a :focus style: the border switches to blue and a soft blue glow (box-shadow) appears around the field the moment it receives keyboard or click focus. This is built into the base .form-control rules, not an opt-in class.

<input type="text" class="form-control" placeholder="Click into this field to see the focus glow">

2. Disabled Inputs: [disabled]

Add the plain HTML disabled attribute (no Bootstrap class required) to grey out a field, block user interaction with it, and exclude its value from form submission entirely.

<input type="text" class="form-control" value="TrailMap Free Plan" disabled>

3. Readonly Inputs: readonly

Add the readonly attribute to let the field keep its normal (not greyed-out) look and stay focusable and selectable, while blocking the user from editing its value. Unlike disabled, a readonly field's value is still submitted with the form.

<input type="text" class="form-control" value="TM-48213" readonly>
<!-- e.g. a system-generated trail submission ID the user can copy but not edit -->

4. Validation States: .has-success / .has-warning / .has-error

Add one of these three classes to the surrounding .form-group (not the input itself) to tint the label, the input's border/focus glow, and any .help-block text inside it to match. Pair the class with a short <span class="help-block"> message so the user sees why the field is flagged.

<div class="form-group has-error">
  <label for="trailName">Trail name</label>
  <input type="text" class="form-control" id="trailName">
  <span class="help-block">Trail name is required.</span>
</div>

<div class="form-group has-success">
  <label for="trailDistance">Distance (mi)</label>
  <input type="text" class="form-control" id="trailDistance" value="4.2">
</div>

5. Feedback Icons: .has-feedback

Add .has-feedback alongside a validation state class on the .form-group, then place a Glyphicon <span> with class .form-control-feedback right after the input. Bootstrap positions the icon inside the field automatically, on its right edge.

<div class="form-group has-error has-feedback">
  <label for="trailName">Trail name</label>
  <input type="text" class="form-control" id="trailName">
  <span class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>
  <span class="help-block">Trail name is required.</span>
</div>

6. Worked Example: TrailMap Required-Field Error

A submitted "Submit a Trail" form where the trail name was left blank: the field shows .has-error with a feedback icon and a help message, while the distance field the visitor filled in correctly shows .has-success.

<form class="form-horizontal">
  <div class="form-group has-error has-feedback">
    <label for="trailName" class="col-sm-2 control-label">Trail name</label>
    <div class="col-sm-10">
      <input type="text" class="form-control" id="trailName">
      <span class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>
      <span class="help-block">Trail name is required.</span>
    </div>
  </div>
  <div class="form-group has-success has-feedback">
    <label for="trailDistance" class="col-sm-2 control-label">Distance (mi)</label>
    <div class="col-sm-10">
      <input type="text" class="form-control" id="trailDistance" value="4.2">
      <span class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true"></span>
    </div>
  </div>
</form>
Next up: that distance field could use a "mi" unit label built right into the input — head to Input Groups to see .input-group-addon and .input-group-btn.