Text Input
Concept
The element where someone types a value directly, used for values you can't turn into a list in advance.
Why it exists
When every value was collected as free text, the same field arrived in a different shape from every person. One phone number field accumulated 010-1234-5678, 01012345678, and +82 10 1234 5678 side by side, and a date field took both 2026-09-16 and 16/09/2026. Whoever received the data had to guess afterward what each one meant. The bill arrives months later, when somebody writes a script to work out which format each stored row used.
The experience on the other side was no better. A malformed value produced an error only after the submit button, and often the error didn't say which field caused it. Plenty of people saw the same error three times on a signup screen and left, and because they left without knowing what was wrong, no ticket got filed either.
So collection methods split by the type of value. Anything you can list, people pick from a list. Anything with competing formats, like a date, gets picked off a calendar with a date picker. Only the values that genuinely can't be listed — a name, a search term — come in as typed text. This part covers what's left, which is why guiding the format and returning malformed values are part of the component rather than extras around it.
How it works
One field is made of five parts.
- The label. It says what goes in the field, and it lives outside the box. It has to stay visible after typing starts. A label that vanishes into the box is a label you lose at the exact moment someone reviews what they entered.
- The input area. One line for names and emails, multiple lines for descriptions and notes. A multi-line box communicates the expected length through its height, so a two-line box and a ten-line box are different decisions.
- The helper text. Format and constraints: at least eight characters, digits only. It earns its place only if it's visible before typing starts. Placed under the field and kept there through typing is the version that works.
- The error message. Directly under the field. Collected at the top of the screen instead, it makes people hunt for which field to fix.
- The states. Default, focused, filled, error, disabled, and read-only — six of them. Read-only is the one that goes missing most, which leaves nowhere to render a field for a user without permission.
When you validate decides most of the usability. Validate while typing and a red border appears two characters into an email address; you're telling someone they're wrong before they've finished. Checking once when the cursor leaves the field, and again on submit, works better. The reverse is true while someone is correcting: if the field is already in an error state, clear the error as soon as they start changing it. Two passes, one on blur and one on submit, cover almost everything without ever calling a half-typed value wrong.
Rather than rejecting a malformed value, accept it and clean it. Take the phone number with or without hyphens and normalize it on save. Strip leading and trailing whitespace. Normalizing once means the stored format is decided in one place rather than in every form that touches it.
Handle character limits by showing rather than blocking. In a field that takes 40 characters, count down what's left, and if they go over, say so instead of truncating. Truncate silently and the person doesn't know why their text got shorter.
On mobile, specify the keyboard along with the field. A numeric keypad on a digits-only field measurably cuts entry time. The first thing accessibility asks for here is that the label be associated with the input element; without the association, a screen reader announces a box and never says what belongs in it.
Where it shows up
Four places fit this part.
- Values that can't be listed. Names, titles, search terms.
- Short values with a fixed format. Email and password, where format guidance and error text matter most.
- Long prose. A multi-line box taking a support message or a description.
- Search. Results narrow as the person types, so unlike the others it needs no validation at all. What gets typed there is a query rather than a value to keep, which is what removes the need.
Where it doesn't fit is equally clear, and the count of options is usually the whole decision. With a fixed set of options, fold them into a select; past a few dozen candidates, switch to a combobox that narrows as you type. Take 200 country names as free text and you will store Korea, South Korea, and Republic of Korea together.
Pagedeck reversed this call once on its signup screen. Company size started as a text field, and the values arriving included "30", "thirty", "30-50", and "under 50" across more than twenty variants. Noa switched it to five radio options, the values collapsed to five, and signup drop-off fell slightly. The job title field stayed as text, though: every attempt at a list came back half "other." Both calls came from reading what had actually been stored, not from a preference about form design.
How it sounds at work
"Make this a select instead of a text input. We're getting twenty variants."
The value can be listed, so it should be picked.
"The format guidance is in the placeholder, so it disappears once typing starts."
The guidance is absent exactly when it's needed.
"Drop the red border while typing. Validate when the cursor leaves the field."
Asking to move the validation moment.
Those lines land at mockup review and just before implementation. When Noa brings all six states of a field, Theo asks about the validation moment and the stored format. Going into implementation without those two settled means cleaning the data again later.
What people get wrong
The common belief is that faint example text inside the box can stand in for guidance. It saves space and appears to inform at the same time. Space saved on a label is the cheapest space in a layout to give back. But a placeholder disappears the moment typing starts, and the moment someone wants to check the format is the moment they're typing — so the guidance isn't on screen when it's wanted. Using it instead of a label is worse. On a fully filled screen, nothing remains to say what any field was for.
The other frequent belief is that restricting input produces clean data. Narrowing what you accept does reduce cleanup, so it reads that way. But what gets blocked is people, and what gets filtered isn't only bad values. Reject special characters and anyone whose name carries a hyphen or an apostrophe can't sign up; block pasting and anyone using a password manager is stuck. Accepting broadly and normalizing on save produces cleaner data than either.
Where to go next
- UI component
see which group this part belongs to and what sits beside it
- Select
put the pick-from-a-list side next to it and settle which to use when
Last updated 2026-09-16