Skip to content

Accessibility specialists

  • About
  • Services
  • Blog
  • Resources
Email us
  1. Home
  2. Resources
  3. Accessible components library
  4. Text input

Pages in this section

Components

  • Accordion
  • Breadcrumbs
  • Dialog
  • Disclosure
  • Pagination
  • Tabs
  • Text input
    • Accessibility requirements
    • Test scenarios
  • Textarea

More information

  • Accessibility requirements
  • Compatibility notes
  • Glossary
  • Test steps
  • View the project on GitHub

Text input

The text input component is a form control that lets people enter a single line of text.

It can be useful when you need to collect information, however when data is required in a specific format, it can introduce errors which need to be handled.

Example

Open this example in a new tab
  • HTML
  • CSS
<form id="tl-text-input-demo">
  <div class="tl-text-input">
    <label for="input-1"> Full name </label>

    <p id="input-1-hint" class="hint-text">
      Your full name as it appears on your passport
    </p>

    <input
      id="input-1"
      type="text"
      autocomplete="name"
      aria-describedby="input-1-hint"
    />
  </div>

  <button hidden>Submit</button>
</form>
/* -------------------------------------------------------------------------- */
/* Text Input                                                                 */
/* -------------------------------------------------------------------------- */

.tl-text-input {
  --colour-text: var(--tl-colour-text, #222222);
  --colour-background: var(--tl-colour-page, #ffffff);
  --colour-border: var(--tl-colour-text, #222222);
  --colour-hint: var(--tl-colour-grey, #666666);
  --colour-error: var(--tl-colour-error, #ca3535);
  --colour-focus-highlight: var(--tl-colour-highlight-focus, #7f238b);
  --colour-focus-contrasting: var(--tl-colour-text, #222222);
}

.tl-text-input {
  display: flex;
  flex-direction: column;
  gap: 0.5em;
  max-inline-size: 60ch;
  padding: 1rem;
  color: var(--colour-text);
}

.tl-text-input input {
  min-block-size: 44px;
  padding: 0.5em;
  font-size: 1rem;
  color: var(--colour-text);
  background-color: var(--colour-background);
  border: 2px solid var(--colour-border);
  border-radius: 0;
}

.tl-text-input label {
  font-weight: 700;
}

.tl-text-input .hint-text {
  margin-block: 0;
  color: var(--colour-hint);
}

.tl-text-input input:focus-visible {
  outline: 5px solid var(--colour-focus-highlight);
  box-shadow: inset 0 0 0 2px var(--colour-focus-contrasting);
}

.tl-text-input--error {
  padding-inline-start: 1.5rem;
  border-inline-start: 0.4rem solid var(--colour-error);
}

.tl-text-input--error .error-message {
  margin-block: 0;
  font-weight: 700;
  color: var(--colour-error);
}

.tl-text-input--error input:not(:focus-visible) {
  border-color: var(--colour-error);
}

button {
    margin: 1rem;
  }
  • HTML
  • CSS
<div class="tl-text-input tl-text-input--error">
  <label for="input-1"> Full name </label>

  <p id="input-1-hint" class="hint-text">
    Your full name as it appears on your passport
  </p>

  <p class="error-message" id="input-1-error">
    <span class="visually-hidden">Error: </span>
    Enter your full name
  </p>

  <input
    id="input-1"
    type="text"
    autocomplete="name"
    aria-invalid="true"
    aria-describedby="input-1-hint input-1-error"
  />
</div>
/* -------------------------------------------------------------------------- */
/* Text Input                                                                 */
/* -------------------------------------------------------------------------- */

.tl-text-input {
  --colour-text: var(--tl-colour-text, #222222);
  --colour-background: var(--tl-colour-page, #ffffff);
  --colour-border: var(--tl-colour-text, #222222);
  --colour-hint: var(--tl-colour-grey, #666666);
  --colour-error: var(--tl-colour-error, #ca3535);
  --colour-focus-highlight: var(--tl-colour-highlight-focus, #7f238b);
  --colour-focus-contrasting: var(--tl-colour-text, #222222);
}

.tl-text-input {
  display: flex;
  flex-direction: column;
  gap: 0.5em;
  max-inline-size: 60ch;
  padding: 1rem;
  color: var(--colour-text);
}

.tl-text-input input {
  min-block-size: 44px;
  padding: 0.5em;
  font-size: 1rem;
  color: var(--colour-text);
  background-color: var(--colour-background);
  border: 2px solid var(--colour-border);
  border-radius: 0;
}

.tl-text-input label {
  font-weight: 700;
}

.tl-text-input .hint-text {
  margin-block: 0;
  color: var(--colour-hint);
}

.tl-text-input input:focus-visible {
  outline: 5px solid var(--colour-focus-highlight);
  box-shadow: inset 0 0 0 2px var(--colour-focus-contrasting);
}

.tl-text-input--error {
  padding-inline-start: 1.5rem;
  border-inline-start: 0.4rem solid var(--colour-error);
}

.tl-text-input--error .error-message {
  margin-block: 0;
  font-weight: 700;
  color: var(--colour-error);
}

.tl-text-input--error input:not(:focus-visible) {
  border-color: var(--colour-error);
}
  • HTML
  • CSS
<div class="tl-text-input">
  <label for="input-1"> Middle name (optional) </label>

  <input id="input-1" type="text" autocomplete="additional-name" />
</div>
/* -------------------------------------------------------------------------- */
/* Text Input                                                                 */
/* -------------------------------------------------------------------------- */

.tl-text-input {
  --colour-text: var(--tl-colour-text, #222222);
  --colour-background: var(--tl-colour-page, #ffffff);
  --colour-border: var(--tl-colour-text, #222222);
  --colour-hint: var(--tl-colour-grey, #666666);
  --colour-error: var(--tl-colour-error, #ca3535);
  --colour-focus-highlight: var(--tl-colour-highlight-focus, #7f238b);
  --colour-focus-contrasting: var(--tl-colour-text, #222222);
}

.tl-text-input {
  display: flex;
  flex-direction: column;
  gap: 0.5em;
  max-inline-size: 60ch;
  padding: 1rem;
  color: var(--colour-text);
}

.tl-text-input input {
  min-block-size: 44px;
  padding: 0.5em;
  font-size: 1rem;
  color: var(--colour-text);
  background-color: var(--colour-background);
  border: 2px solid var(--colour-border);
  border-radius: 0;
}

.tl-text-input label {
  font-weight: 700;
}

.tl-text-input .hint-text {
  margin-block: 0;
  color: var(--colour-hint);
}

.tl-text-input input:focus-visible {
  outline: 5px solid var(--colour-focus-highlight);
  box-shadow: inset 0 0 0 2px var(--colour-focus-contrasting);
}

.tl-text-input--error {
  padding-inline-start: 1.5rem;
  border-inline-start: 0.4rem solid var(--colour-error);
}

.tl-text-input--error .error-message {
  margin-block: 0;
  font-weight: 700;
  color: var(--colour-error);
}

.tl-text-input--error input:not(:focus-visible) {
  border-color: var(--colour-error);
}

What problems it solves

The text input component allows people to enter free form text, instead of choosing from a list of predefined options.

When to use it

Use a text input when:

  • It is not possible to predict users' answer
  • People are expected to enter a single line of text

When not to use it

Do not use a text input when:

  • People's possible answers are limited and can be predicted (use radio buttons, checkboxes or a <select> instead)
  • People may need to enter multiple lines of text (use the textarea component instead)
  • People are expected to enter non-text values, such as a telephone number

Where to use it

Text inputs are commonly used in forms to collect people's answers and personal information, such as people's name or the company they work for.

Assistive technology compatibility

This component has been tested with the following browsers and assistive technologies.

Assistive technology Result Notes
Keyboard No issues No notes
Voice Access/Chrome 154.0.8/Windows 11 No issues No notes
JAWS 2026.2603.86/Chrome 154.0.8/Windows 11 No issues No notes
NVDA 2026.1.1/Firefox 157.0/Windows 11 No issues No notes
VoiceOver/Safari macOS Tahoe 26.6 No issues No notes
VoiceOver/Safari/iOS 26.0 No issues No notes
TalkBack/Chrome 154.0.8/Android 17 No issues No notes
Windows Contrast themes No issues No notes
Windows Magnifier and/or Apple Zoom No issues No notes
Browser zoom No issues No notes
prefers-reduced-motion Not applicable There are no animations to reduce

Last updated: 13 October 2026.

Back to top

We like to listen

Wherever you are in your accessibility journey, get in touch if you have a project or idea.

hello@tetralogical.com
Colour scheme

60 Windsor Avenue, London, SW19 2RR, UK +44 (0)20 8895 6768 hello@tetralogical.com

© TetraLogical Services Ltd. All Rights Reserved. Company number 12951928.

Privacy policy • Accessibility statement • Code of ethics