Skip to main content

Looking for the web component? See Text field (web component)

Variations

The following configuration demonstrates a bare-minimum text field pattern. All other variations are modifications of this configuration.

<bolt-input-control>
  <label for="INPUT_ID">
    <span>Label</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <input
      id="INPUT_ID"
      type="text"
    />
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Label</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <input
      id="INPUT_ID"
      type="text"
    />
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Label</span>
  </label>
  <bolt-input-facade>
    <input
      id="INPUT_ID"
      required
      type="text"
    />
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Label</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <input
      aria-describedby="HELP_ID"
      id="INPUT_ID"
      type="text"
    />
  </bolt-input-facade>
  <footer>
    <p
      class="bolt-help"
      id="HELP_ID
    >
      This is some instructional text.
    </p>
  </footer>
</bolt-input-control>
<bolt-input-control class="bolt-disabled">
  <label for="INPUT_ID">
    <span>Label</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <input
      disabled
      id="INPUT_ID"
      type="text"
    />
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control class="bolt-invalid">
  <label for="INPUT_ID">
    <span>Label</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <input
      aria-describedby="ERROR_ID"
      id="INPUT_ID"
      type="text"
    />
  </bolt-input-facade>
  <footer>
    <div
      class="bolt-error"
      id="ERROR_ID"
    >
      <bolt-field-error>
        This field is required.
      </bolt-field-error>
    </div>
  </footer>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Label</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <input
      id="INPUT_ID"
      type="text"
    />
    <bolt-icon
      class="bolt-tail"
      color="theme-error"
      name="exclamation-circle-filled"
    ></bolt-icon>
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Label</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <input
      id="INPUT_ID"
      type="text"
    />
    <bolt-icon
      class="bolt-tail"
      color="theme-info"
      name="info-square-filled"
    ></bolt-icon>
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Label</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <input
      id="INPUT_ID"
      type="text"
    />
    <bolt-icon
      class="bolt-tail"
      color="theme-info"
      name="question-circle-filled"
    ></bolt-icon>
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Label</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <input
      id="INPUT_ID"
      type="text"
    />
    <bolt-icon
      class="bolt-tail"
      color="theme-success"
      name="checkmark-bold-circle-filled"
    ></bolt-icon>
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Label</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <input
      id="INPUT_ID"
      type="text"
    />
    <bolt-icon
      class="bolt-tail"
      color="theme-warning"
      name="exclamation-triangle-filled"
    ></bolt-icon>
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Label</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <input
      id="INPUT_ID"
      type="text"
    />
    <bolt-waiting-indicator
      class="bolt-tail"
      minimal
    ></bolt-waiting-indicator>
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Payment amount</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <span class="bolt-prefix bolt-symbol">$</span>
    <input
      id="INPUT_ID"
      type="text"
    />
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Policy number</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <span class="bolt-prefix">1234-</span>
    <input
      id="INPUT_ID"
      type="text"
      value="999999999"
    />
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Contribution amount</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <input
      id="INPUT_ID"
      type="text"
    />
    <span class="bolt-suffix bolt-symbol">%</span>
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Username</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <input
      id="INPUT_ID"
      type="text"
    />
    <span class="bolt-suffix">@example.com</span>
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Label</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <input
      class="bolt-align-right"
      id="INPUT_ID"
      type="text"
      value="test 123"
    />
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Search</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <input
      id="INPUT_ID"
      type="search"
    />
    <button
      aria-label="search"
      class="bolt-tail"
      type="button"
    >
      <bolt-icon
        name="search"
        title="search"
      ></bolt-icon>
    </button>
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Password</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <input
      id="INPUT_ID"
      type="password"
      value="super secret"
    />
    <button
      aria-label="show password"
      class="bolt-tail"
      type="button"
    >
      <bolt-icon
        name="eye-show"
        title="show password"
      ></bolt-icon>
    </button>
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Password</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade>
    <input
      id="INPUT_ID"
      type="text"
      value="super secret"
    />
    <button
      aria-label="hide password"
      class="bolt-tail"
      type="button"
    >
      <bolt-icon
        name="eye-hide"
        title="hide password"
      ></bolt-icon>
    </button>
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Label</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-contextual-help
    heading="Help text heading"
    type="push"
  >
    <p>Help text body.</p>
  </bolt-contextual-help>
  <bolt-input-facade>
    <input
      id="INPUT_ID"
      type="text"
    />
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control class="bolt-disabled">
  <label for="INPUT_ID">
    <span>Label</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-contextual-help
    disabled
    heading="Help text heading"
    type="push"
  >
    <p>Help text body.</p>
  </bolt-contextual-help>
  <bolt-input-facade>
    <input
      disabled
      id="INPUT_ID"
      type="text"
    />
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Label</span>
    <span class="bolt-annotation bolt-optional">
      (optional)
    </span>
  </label>
  <bolt-input-facade class="bolt-hug-content">
    <input
      id="INPUT_ID"
      size="20"
      type="text"
    />
  </bolt-input-facade>
</bolt-input-control>
<bolt-input-control>
  <label for="INPUT_ID">
    <span>Number input (with spin arrows)</span>
    <span class="bolt-annotation bolt-optional">(optional)</span>
  </label>
  <bolt-input-facade>
    <input
      id="INPUT_ID"
      class="bolt-showarrows"
      type="number"
      step="5"
      min="0"
      max="100"
    />
  </bolt-input-facade>
</bolt-input-control>
Code reference

The HTML implementation provides full control over the markup. However, it is up to the consumer to implement all interaction logic.

If you want Bolt to handle the interaction logic, check out the web component implementation.

This implementation should be compatible with @angular/forms without the need for additional dependencies.

Refer to MDN for best practices on using the HTML <input> element.

The <bolt-input-facade> custom element is designed exclusively for use within the input control pattern in order to encapsulate the complex CSS required to present a styled input control.

All APIs built for <bolt-input-facade> should be considered "private" and are subject to change at any time, without warning. Any use of the custom element outside of documented patterns shall be done so at consumer's own risk.

<!-- Root (REQUIRED) -->
<bolt-input-control
  class="
    [bolt-disabled]
    [bolt-invalid]
  "
>
  <!-- Label (REQUIRED) -->
  <label for="INPUT_ID">
    <span>Label</span>

    <!-- "Optional" Annotation (optional) -->
    <span class="bolt-annotation bolt-optional"> (optional) </span>
  </label>

  <!-- Contextual help (optional) -->
  <bolt-contextual-help type="push" [disabled] ...> ... </bolt-contextual-help>

  <!-- Facade (REQUIRED) -->
  <bolt-input-facade
    class="
      [bolt-hug-content]
    "
  >
    <!-- Prefix (optional) -->
    <span class="bolt-prefix [bolt-symbol]">...</span>

    <!-- Input (REQUIRED) -->
    <input
      [aria-describedby="[ERROR_ID] [HELP_ID]"
      ]
      class="
        [bolt-align-right]
      "
      [disabled]
      id="INPUT_ID"
      [required]
      [size="..."
      ]
      type="..."
      ...
    />

    <!-- Suffix (optional) -->
    <span class="bolt-suffix [bolt-symbol]">...</span>

    <!-- Status indicator (optional) -->
    <bolt-icon class="bolt-tail" color="..." name="..."></bolt-icon>

    <!-- Waiting indicator (optional) -->
    <bolt-waiting-indicator class="bolt-tail" minimal></bolt-waiting-indicator>

    <!-- Button (optional) -->
    <button aria-label="A11Y_LABEL" class="bolt-tail" type="button">
      <bolt-icon name="..." title="A11Y_LABEL"></bolt-icon>
    </button>
  </bolt-input-facade>

  <!-- Footer (optional) -->
  <footer>
    <!-- Instructional text (optional) -->
    <p class="bolt-help" id="HELP_ID">Instructional text...</p>

    <!-- Error message (optional) -->
    <div class="bolt-error" id="ERROR_ID">
      <bolt-field-error> Error message... </bolt-field-error>
    </div>
  </footer>
</bolt-input-control>

Unless specified, elements should be defined in the order presented above.

A select control is comprised of the following items:

  • Root (REQUIRED)
    • MAY apply [bolt-invalid] to apply "invalid" appearance to the input element.
    • MAY apply [bolt-disabled] to apply "disabled" appearance to the input element.
  • Label (REQUIRED)
    • MUST have a [for] attribute with value matching the [id] of the input.
  • Annotation (optional)
    • When present, communicates that the text field is not critical for workflow progression.
    • MUST match .bolt-annotation.bolt-optional CSS selector.
    • MUST be an inline element inside of label element.
    • Should have "(optional)" as inner text.
  • Contextual help (optional)
    • MUST have [type="push"].
    • See contextual help component for more information.
  • Facade (REQUIRED)
    • MUST be present to display the text field on screen.
  • Prefix (optional)
    • MUST match .bolt-prefix CSS selector
    • MAY contain [bolt-symbol]
  • Input (REQUIRED)
    • Refer to MDN for best practices on using the HTML <input> element.
    • MUST have an [id] attribute with value matching the [for] of the label.
    • MAY have [aria-describedby] attribute, depending on use of Instructional text or Error
    • MAY use .bolt-align-left (default) or .bolt-align-right CSS selectors
  • Suffix (optional)
    • MUST match .bolt-suffix CSS selector
    • MAY contain [bolt-symbol]
  • Status indicator (optional)
    • MUST match .bolt-tail CSS selector.
    • See icon component for more information.
  • Waiting indicator (optional)
    • MUST match .bolt-tail CSS selector.
    • See waiting-indicator component for more information.
  • Button (optional)
    • Refer to MDN for best practices on using the HTML <button> element.
    • See icon component for more information.
  • Footer (optional)
    • Supports wrapping optional elements to be associated with the text field.
  • Instructional text (optional)
    • MUST match .bolt-help CSS selector.
    • MUST have [id] attribute with value matching the [aria-describedby] attribute of the input.
    • MUST be wrapped in the footer.
  • Error (optional)
    • Defines a single error message.
    • A <bolt-field-error> element is recommended.
    • MUST have an [id] attribute that matches the [aria-describedby] attribute of the input.
    • MUST be wrapped in the footer.
    • Error and disabled state should not be used at the same time.
Design guidelines
  • A Text field should always be paired with a field label to communicate expected input. Don't remove the label, as it creates accessibility and usability issues.
    • A field label is not needed when the component is used inside a table cell if the column header and table are coded to provide appropriate accessibility, and by extension context for the Text field.
  • The first letter entered in a Text field should automatically be capitalized, except when asking for a username, password, and/or email address.
  • Allow users to enter formatted numbers (e.g., telephone number, Social Security number) inside a single Text field to ensure accessibility for visually impaired users.
  • Use "type" to differentiate virtual keyboards on mobile devices (e.g., number, tel, text, range, url, etc.). This helps to optimize input of frequently used characters inside that Text field.
    • Common text field types that require optimized virtual keyboards for entering numbers, text or mixed formats include:
      • Number (such as phone number, credit card number or PIN)
      • Text (such as name, username or URL)
      • Mixed format (such as email address, street address or search query)
  • Use confirm (re-type) fields for collecting information such as an email address, account number, routing numbers or password. The time and effort it can take a user or company to correct this information later can be significant. Entering this information twice on a form takes a fraction of that time and effort.
  • Include a static prefix or suffix in Text fields for entering units like dollars or percentages.
  • Allow users to show and hide the characters entered into security-sensitive text fields for passwords, credit card numbers, Social Security numbers, etc.
  • Use the instructional text below a Text field to display its valid input format.
  • Use Contextual help in conjunction with the field label to provide answers to common questions about expected field input.
  • Avoid pre-populating a Text field.
  • Text field should not be both in error and disabled states at the same time. While this might be technically possible, from a user standpoint, these should be mutually exclusive.
  • Avoid enforcing rigid formatting rules; consider potential data variations or masking to account for formatting.
  • Input validation and error messaging should, depending on the context of use, occur after users either:
    • submit a form (form-level validation).
    • enter one or more characters (delayed onInput, mid-form validation).
    • exit the field (onBlur, frontend validation only).
  • It is generally advised to stack Text fields (and other input fields) when multiple fields are on a screen. This is so fields don't move out of sight for those who have higher levels of zoom set in their browsers.
    • Some exceptions may be with city and state Text fields, middle initial fields, and in equations where field widths are defined by the number of digits allowed.
  • When users need to enter a number of characters that easily fits within the width of a typical text field.
  • When entering large amounts of text, avoid using Text field, use Text area instead.
  • When users need to select multiple values, avoid using Text field, use Checkbox instead.
  • Avoid using Text field for entering dates and times, with the exception of entering a birthdate. Use Date picker or a date/time picker.

Do

  • Use when needing to enter short, single-line text or numbers.
  • Ensure the Text field has a visible, concise and meaningful label for context.
  • Use informational text to show hints, formatting, and requirements.
  • Make Text field widths proportional to content and align them to grid columns.
  • Use Contextual help in conjunction with the label for common questions about expected input.
  • Use confirm (re-type) fields for collecting critical information, (e.g. a password.)
  • Allow users to show and hide characters in security-sensitive Text fields.
  • Use for entering a password, URL, phone number, or email address.
  • Favor stacking Text fields instead of placing them side-by-side.

Don't

  • Don't remove the label, as it creates accessibility and usability issues.
  • Don't use placeholder text as a replacement for a text field label.
  • Don't use placeholder text to display hints, formatting or requirements as it can cause a user to lose context since placeholder text disappears once a user clicks in the field.
  • Don't place unrelated fields on the same line. (e.g. Last name and address).
  • Don't center text in a Text field or hang the Text field in the gutter.
  • Don't make a Text field excessively wide just to fill space.
  • Don't remove field borders.
  • Text field labels, instructional text and error messages use sentence case.
  • Instructional text should clarify the format of valid user input.
  • Error messages should be clear and concise, including a period.
Accessibility
  • Warning: The use of placeholder text as the sole label for a field is not a best practice and a violation of Success Criterion 3.3.2.
  • It is important for form field labels to always remain visible, to help users understand what they're working with. Placeholder text, or text inside the form field, should not be used as a label because it disappears when the user starts typing. This can be confusing, especially for people with cognitive disabilities who might forget what the field is for. It's also a problem for those who use speech-to-text tools because it makes it hard to understand what to say to activate the field.
  • The placeholder attribute of the HTML <input> element should not be used as an alternative to a label, because placeholder text will disappear when the user enters data into the field and additionaly, it prevents screen readers from announcing placeholder text after data has been entered.

Display settings

Note: not all settings persist across pages

Default Compact (-1) Sparse (+1) XL (default) 2XL 3XL Default Min Max Light (default) System Dark Branded (default) Unbranded