Accessible Forms: Placeholder Text Is Not a Label
Placeholder text disappears the moment someone starts typing, which is exactly when they need it most.
There’s a design trick that took over web forms about a decade ago and never left: delete the label, put the label’s text inside the field as gray placeholder text, and enjoy how clean everything looks. I understand the appeal. A form with floating gray hints looks lighter than a form with labels stacked above every input. Designers get a tidier mockup. Everyone moves on.
The problem is that placeholder text disappears the moment someone starts typing. That sounds trivial until you think about when people actually need the label. It’s not before they type. It’s while they’re typing, and especially after, when they look back over the form to check what they entered. If the label was the placeholder, it’s gone. The user is now staring at a grid of filled boxes with no way to confirm which one was supposed to be the billing zip code and which was the shipping one. So they do what anyone would do: they select the text, delete it to make the hint reappear, read it, and retype. Or they guess. Guessing on a payment form is how you get failed transactions, and failed transactions are how you get abandoned carts.
I built GazeSite, a tool that audits websites, and forms with placeholder-only fields are one of the most common things it flags. Not because it’s an exotic failure, but because it’s an easy one to ship. The form works fine when you’re the person who built it and already knows what every field means. It fails for everyone arriving cold, which is to say, for your customers.
The accessibility case is even more direct. Screen readers are inconsistent about announcing placeholder text, and even when they do announce it, the placeholder is semantically a hint, not a name. The HTML spec agrees: the placeholder attribute is explicitly not a substitute for a label. When a field has a real label element associated with it, either by wrapping the input or by pointing at it with a for attribute, a screen reader user hears the field’s name when they land on it, every time, no matter what’s typed in it. That association also gives you something sighted users benefit from without noticing: clicking the label focuses the field. On a phone, where inputs are small and thumbs are not, the label becomes extra tap target for free.
There’s a subtler problem too. Placeholder text is conventionally rendered in light gray, and light gray on white usually fails contrast requirements. So even in the brief window when the hint is visible, a meaningful fraction of your visitors, anyone with low vision, anyone on a cheap screen in sunlight, anyone over fifty, can barely read it. You’ve taken the one piece of text that explains the field and made it the hardest text on the page to see.
People sometimes defend the pattern with floating labels, the animation where the placeholder shrinks and slides up when you focus the field. Floating labels are genuinely better than placeholders alone, because the label persists. But they’re a lot of implementation effort to arrive at roughly where a plain static label started, and they still begin life as low-contrast text inside the box, which some users will mistake for a pre-filled value. I’ve watched people try to submit a form because every field “already had something in it.”
The fix costs almost nothing. Put a visible label above each field. Associate it with the input in the markup, not just visually. If you want a hint, like the expected format of a date, keep it as separate helper text below the field, where it stays visible while the user types the thing it’s hinting about. Use the placeholder attribute for what it’s good at, which is a brief example, not a name. “e.g. [email protected]” as a placeholder under a label that says Email is fine. “Email” as the only identification the field will ever have is not.
What I find interesting about this pattern is what it reveals about how design decisions get made. Nobody chose to make their checkout harder. They chose to make their mockup prettier, and the cost landed somewhere they couldn’t see: on the screen reader user who tabbed into an unnamed field, on the distracted person filling out the form in line at a coffee shop, on everyone who typed something, second-guessed it, and had no way to check. The costs of minimalism are real; they’re just paid by someone other than the designer, at a time other than the design review.
The business framing matters here more than the compliance framing. Yes, WCAG requires that inputs have accessible names, and placeholder-only forms usually fail that. But the reason to fix it isn’t to pass an audit. It’s that forms are where money changes hands. A form is the last thing standing between an interested visitor and a completed purchase or signup, and every ounce of friction there is friction at the most expensive possible point in the funnel. Labels are the cheapest conversion optimization I know of. They’re one line of HTML, they help everyone, and their absence is silently taxing you on every submission.
If you look at your own forms right now and see gray text sitting inside empty boxes doing the work a label should do, that’s worth an afternoon. It might be the highest-leverage afternoon your checkout gets this year.
More articles
Before paying a stranger on the internet, buyers run a fast, mostly unconscious audit — and most sites fail it on details the owner stopped seeing years ago.
Read →Once you understand your own product, you lose the ability to see your landing page the way a newcomer does.
Read →A badly built modal splits your page into two layers, strands screen reader users in the wrong one, and the platform already fixed this if you let it.
Read →