Skip to component content

A native input primitive with Bootstrap form semantics for labeled, helper-aware, and validated fields.

Usage

Use .form-control inputs for one-line values such as names, emails, search terms, urls, tokens, and numbers. Choose the native type that matches the data so mobile keyboards, browser validation, and autofill behavior work with the field instead of against it.

Pair every standalone input with a visible label or an accessible name, and connect helper or error text with aria-describedby. Keep placeholder text as an example value only; it should not replace the label or carry required instructions.

Set state on the native input: required for required fields, readonly when the value can be copied but not changed, disabled when it is unavailable, and invalid state when validation fails. Use Bootstrap sizing and form-control variants only after the field's semantics are already clear.

API Key

Use a labeled single input with helper text.

Input
Your API key is encrypted and stored securely.
<div class="field">
  <label class="form-label" for="input-api-key">API Key</label>
  <input class="form-control" id="input-api-key" type="text" placeholder="sk-..." aria-describedby="input-api-key-help">
  <div class="field-description form-text" id="input-api-key-help">Your API key is encrypted and stored securely.</div>
</div>

Basic

Use a single input when surrounding context or an explicit aria-label provides the accessible name.

Input
<div class="field">
  <input class="form-control" type="text" placeholder="Enter your text" aria-label="Input">
</div>

Field

Wrap a label and input together in a .field container to keep spacing consistent under Bootstrap form semantics.

Input
We'll only use this to send you updates.
<div class="field">
  <label class="form-label" for="input-field-email">Email</label>
  <input class="form-control" id="input-field-email" type="text" placeholder="you@example.com" aria-describedby="input-field-email-help">
  <div class="field-description form-text" id="input-field-email-help">We&#39;ll only use this to send you updates.</div>
</div>

Field group

Group related fields inside a .field-group to keep rhythm and spacing token-driven.

Input
Developer profile
Shown on the shared team roster.
Displayed in activity headers.
Used for routing and search matching.
<fieldset class="field-fieldset">
  <legend class="field-legend">Developer profile</legend>
  <div class="field-description form-text">Shown on the shared team roster.</div>
  <div class="field-group">
    <div class="field">
      <label class="form-label" for="input-first-name">First name</label>
      <input class="form-control" id="input-first-name" type="text" placeholder="Ada" aria-describedby="input-first-name-help">
      <div class="field-description form-text" id="input-first-name-help">Displayed in activity headers.</div>
    </div>
    <div class="field">
      <label class="form-label" for="input-last-name">Last name</label>
      <input class="form-control" id="input-last-name" type="text" placeholder="Lovelace" aria-describedby="input-last-name-help">
      <div class="field-description form-text" id="input-last-name-help">Used for routing and search matching.</div>
    </div>
  </div>
</fieldset>

Read-only

Use readonly on a single field to preserve visible context without editing.

Input
<div class="field">
  <label class="form-label" for="input-default-region">Default region</label>
  <input class="form-control" id="input-default-region" type="text" value="us-east-1" readonly>
</div>

Disabled

Use disabled on a control-level input to block interaction while keeping it readable.

Input
Contact an owner to change the workspace slug.
<div class="field">
  <label class="form-label" for="input-disabled-slug">Workspace slug</label>
  <input class="form-control" id="input-disabled-slug" type="text" placeholder="acme-corp" disabled aria-describedby="input-disabled-slug-help">
  <div class="field-description form-text" id="input-disabled-slug-help">Contact an owner to change the workspace slug.</div>
</div>

Invalid

Use aria-invalid="true" to mark a field as invalid alongside descriptive helper text.

Input
This field contains validation errors.
<div class="field" data-invalid="true">
  <label class="form-label" for="input-invalid">Invalid Input</label>
  <input class="form-control is-invalid" id="input-invalid" type="text" placeholder="Error" aria-invalid="true" aria-describedby="input-invalid-help">
  <div class="field-description form-text" id="input-invalid-help">This field contains validation errors.</div>
</div>

File

Use Bootstrap's native custom file input pattern inside an .input-group.

Input
<div class="field">
  <div class="input-group">
    <input class="form-control" id="input-picture" type="file" aria-label="Upload">
  </div>
</div>

Inline

Place an input field next to a button in a flex row to create a search input with a button.

Input
<div class="d-flex gap-2 w-100">
  <div class="field flex-fill">
    <input class="form-control" type="search" placeholder="Search..." aria-label="Search">
  </div>
  <button class="btn btn-primary" type="button">Search</button>
</div>

Grid

Use a flex row of .field.flex-fill containers to place multiple inputs side by side.

Input
<div class="d-flex flex-wrap gap-3">
  <div class="field flex-fill">
    <label class="form-label" for="input-grid-city">City</label>
    <input class="form-control" id="input-grid-city" type="text" placeholder="Amsterdam">
  </div>
  <div class="field flex-fill">
    <label class="form-label" for="input-grid-postal-code">Postal code</label>
    <input class="form-control" id="input-grid-postal-code" type="text" placeholder="1011 AB">
  </div>
</div>

Required

Use the required attribute to indicate required inputs.

Input
Used to generate the deployment URL.
<div class="field">
  <label class="form-label" for="input-required">
    Project name
    <span class="text-danger">*</span>
  </label>
  <input class="form-control" id="input-required" type="text" placeholder="marketing-site" required aria-describedby="input-required-help">
  <div class="field-description form-text" id="input-required-help">Used to generate the deployment URL.</div>
</div>

Badge

Add a .badge inside the label to highlight a recommended field.

Input
<div class="field">
  <label class="form-label d-flex align-items-center justify-content-between" for="input-badge">
    API endpoint
    <span class="badge text-bg-secondary">Preview</span>
  </label>
  <input class="form-control" id="input-badge" type="text" placeholder="https://api.acme.dev/v1/webhook">
</div>

Input Group

To add icons or text inside an input, wrap it in a Bootstrap .input-group. See the Input Group component for more examples.

Input
https://
<div class="field">
  <div class="input-group">
    <span class="input-group-text">https://</span>
    <input class="form-control" id="input-group-url" type="text" placeholder="example.com" aria-label="Website URL">
  </div>
</div>

Button Group

Use Bootstrap's native .input-group pattern to attach a button to a search input with a shared border. See the Button Group component for button-only groups.

Input
<div class="field">
  <label class="form-label" for="input-button-group-search">Search</label>
  <div class="input-group">
    <input class="form-control" id="input-button-group-search" type="search" placeholder="Type to search..." aria-label="Search">
    <button class="btn btn-outline-secondary" type="button">Search</button>
  </div>
</div>

Form

A full form example composed from a <fieldset>, a .field-group, and labeled fields. See the Fieldset section for the legend/description contract.

Input
Shipping details
Used to calculate delivery time and customs fees.
Order updates are sent to this address.
<form class="field-form needs-validation mx-auto" novalidate>
  <fieldset class="field-fieldset">
    <legend class="field-legend">Shipping details</legend>
    <div class="field-description form-text">Used to calculate delivery time and customs fees.</div>
    <div class="field-group">
      <div class="field">
        <label class="form-label" for="input-form-name">
          Full name
          <span class="text-danger">*</span>
        </label>
        <input class="form-control" id="input-form-name" type="text" placeholder="Ada Lovelace" required>
      </div>
      <div class="field">
        <label class="form-label" for="input-form-email">Email</label>
        <input class="form-control" id="input-form-email" type="text" placeholder="you@example.com" aria-describedby="input-form-email-help">
        <div class="field-description form-text" id="input-form-email-help">Order updates are sent to this address.</div>
      </div>
      <div class="d-flex flex-wrap gap-3">
        <div class="field flex-fill">
          <label class="form-label" for="input-form-phone">Phone</label>
          <input class="form-control" id="input-form-phone" type="text" placeholder="+31 20 123 4567">
        </div>
        <div class="field flex-fill">
          <label class="form-label" for="input-form-country">Country</label>
          <select class="form-select" id="input-form-country" data-selected="nl">
            <option value="nl" selected>Netherlands</option>
            <option value="de">Germany</option>
            <option value="us">United States</option>
          </select>
        </div>
      </div>
      <div class="field">
        <label class="form-label" for="input-form-address">Address</label>
        <input class="form-control" id="input-form-address" type="text" placeholder="Damrak 1, 1012 LG">
      </div>
    </div>
  </fieldset>
  <div class="d-flex gap-2 justify-content-end mt-3">
    <button class="btn btn-outline-secondary" type="reset">Cancel</button>
    <button class="btn btn-primary" type="submit">Submit</button>
  </div>
</form>

RTL

Use the same labeled helper-text pattern across Arabic and Hebrew RTL examples, with English as the LTR comparison.

مفتاح API الخاص بك آمن ومشفر.
<div dir="rtl" class="w-100">
  <div class="field">
    <label class="form-label" for="input-rtl-arabic">مفتاح API</label>
    <input class="form-control" id="input-rtl-arabic" type="text" placeholder="sk-..." aria-describedby="input-rtl-arabic-help">
    <div class="field-description form-text" id="input-rtl-arabic-help">مفتاح API الخاص بك آمن ومشفر.</div>
  </div>
</div>
המפתח שלך מאובטח ומוצפן.
<div dir="rtl" class="w-100">
  <div class="field">
    <label class="form-label" for="input-rtl-hebrew">מפתח API</label>
    <input class="form-control" id="input-rtl-hebrew" type="text" placeholder="sk-..." aria-describedby="input-rtl-hebrew-help">
    <div class="field-description form-text" id="input-rtl-hebrew-help">המפתח שלך מאובטח ומוצפן.</div>
  </div>
</div>
Your key is encrypted and stored securely.
<div dir="ltr" class="w-100">
  <div class="field">
    <label class="form-label" for="input-rtl-english">API Key</label>
    <input class="form-control" id="input-rtl-english" type="text" placeholder="sk-..." aria-describedby="input-rtl-english-help">
    <div class="field-description form-text" id="input-rtl-english-help">Your key is encrypted and stored securely.</div>
  </div>
</div>

Component reference

Status
Accepted
Runtime
native HTML/CSS
Markup
Bootstrap/native HTML
Reference

For more form control options, see the Bootstrap Form controls documentation.

Settings

Theme
Choose how Moo UI looks on this device.
Sidebar
Choose how the sidebar sits on the page.
Theme Builder
Tune catalog tokens and chart colors for this browser.
Base color
Theme color
Chart color
Heading font
Body font
Radius
Direction
Choose the reading direction. RTL flips the layout live.
Reset

Restore the default appearance.