Form Controls

The previous lesson covered the .custom-* classes that give checkboxes, radios, and selects a fully redrawn look. Most of the time, though, you'll reach for Bootstrap 4's default form control styling instead — it keeps the browser's native control behavior but gives text inputs, textareas, plain selects, and checkboxes/radios consistent borders, padding, and focus states. We'll style the trail name and description fields on TrailMap's submission form this way.

Text Inputs and Textareas: .form-control

.form-control is the workhorse class for text-like inputs — <input type="text">, email, number, <textarea>, and more. It sets full width, consistent padding, a border, and a blue focus ring.

<label for="trailName">Trail name</label>
<input type="text" class="form-control" id="trailName" placeholder="e.g. Ridgeline Loop">

<label for="trailDescription">Description</label>
<textarea class="form-control" id="trailDescription" rows="4"></textarea>

Default (Non-Custom) Selects

Add .form-control directly to a plain <select> to match it visually with the text inputs around it, while leaving the browser's native dropdown arrow and open behavior untouched. Contrast this with .custom-select from the previous lesson, which fully redraws the arrow.

<select class="form-control" id="trailRegion">
  <option>Pacific Northwest</option>
  <option>Rocky Mountains</option>
  <option>Appalachian</option>
</select>

Default Checkboxes and Radios: .form-check

Rather than fully restyling checkboxes and radios like .custom-checkbox does, .form-check just cleans up native browser spacing and alignment — the actual checkbox/radio still renders with the browser's own look. Wrap the input in .form-check, give the input .form-check-input, and the label .form-check-label.

<div class="form-check">
  <input class="form-check-input" type="checkbox" id="hasParking">
  <label class="form-check-label" for="hasParking">Trailhead has parking</label>
</div>
<div class="form-check form-check-inline">
  <input class="form-check-input" type="radio" name="season" id="seasonSummer">
  <label class="form-check-label" for="seasonSummer">Summer</label>
</div>

.form-check-inline displays a group of checks side by side instead of stacked, handy for a short list like a season picker.

Sizing: .form-control-lg / .form-control-sm

Add .form-control-lg or .form-control-sm alongside .form-control to scale an input's height, padding, and font size up or down from the default. These also work on plain .form-control selects.

<input type="text" class="form-control form-control-lg" placeholder="Large input">
<input type="text" class="form-control" placeholder="Default input">
<input type="text" class="form-control form-control-sm" placeholder="Small input">

Worked Example: TrailMap Trail Name & Description

Here's the top of TrailMap's "Submit a Trail" form, built entirely with default (non-custom) controls — a large trail name field to draw attention, and a description textarea below it.

<!-- TrailMap: Submit a Trail — name & description -->
<div class="form-group">
  <label for="trailName">Trail name</label>
  <input type="text" class="form-control form-control-lg" id="trailName" name="trail_name" placeholder="e.g. Ridgeline Loop">
</div>
<div class="form-group">
  <label for="trailDescription">Description</label>
  <textarea class="form-control" id="trailDescription" name="description" rows="4" placeholder="What makes this trail worth hiking?"></textarea>
</div>
<div class="form-check">
  <input class="form-check-input" type="checkbox" id="hasParking" name="has_parking">
  <label class="form-check-label" for="hasParking">Trailhead has parking</label>
</div>
Up next: Form Layout covers how to wrap these controls with .form-group and lay out full horizontal and inline forms.