Before I Can Fill It, I Need to Know What You’re Asking
There’s a form I encountered recently that had twelve fields. No labels. Just placeholder text inside each input that disappeared the moment you started typing. If you forgot what a field was asking for, you had to delete everything you’d entered just to see the hint again.
Twelve fields. Zero labels. Infinite frustration.
That’s not a design choice. That’s a barrier. And it’s exactly the kind of thing WCAG 3.3.2: Labels or Instructions exists to dismantle.
The Requirement, Stripped Down
When content requires user input, you must provide labels or instructions.
That’s it. That’s the whole criterion. But the simplicity of the statement belies how often it gets ignored, misinterpreted, or implemented in a way that technically passes a validator while still failing actual human beings.
Let me break down what “labels or instructions” actually means in practice.
A placeholder is a suggestion.
A label is a contract.
Labels: The Non-Negotiable Baseline
A label is text that identifies what a field is asking for. It needs to be:
- Visible — present on the screen at all times, not just when the field is empty
- Programmatically associated — linked to the input via
<label>oraria-labelledbyso screen readers announce the connection
Here’s are the right ways:
<label for="fullname">Full Name</label> <input type="text" id="fullname" name="fullname">
<label for="yes"><input type="radio" id="yes" name="confirm" /> Yes</label>
And here’s the way that makes me question your life choices:
<input type="text" name="fullname" placeholder="Full Name">
Placeholder text is not a label. It disappears on input. It typically has low contrast. Screen readers treat it inconsistently. And once it’s gone, there’s nothing left to remind the user what the field was asking for.
A placeholder is a suggestion. A label is a contract.
Instructions: When a Label Isn’t Enough
Sometimes a label alone doesn’t tell the whole story. That’s where instructions come in.
Think about a password field. The label “Password” is fine, but it doesn’t tell the user that the password needs to be at least 12 characters with one uppercase letter, one number, and one symbol. If they submit and get an error saying “Password doesn’t meet requirements,” you’ve wasted their time.
You could have told them upfront.
Instructions can take many forms:
- Helper text below the field explaining format requirements
- A note above the form explaining what documents to have ready
- Guidance about expected input, like “Enter your date as MM/DD/YYYY”
The key is timing. Instructions must be available before the user acts, not after they fail. 3.3.2 is about prevention. 3.3.1 is about response. They work as a pair—tell people what you need, then tell them what went wrong if they don’t provide it.
What Counts as “Required”?
This trips people up. If a field is required, the user needs to know that before submitting. Not after.
Two common approaches:
<!-- Option 1: Visible asterisk with explanation -->
<label for="email"> Email <span aria-hidden="true">*</span> <span class="sr-only">(required)</span> </label>
<input type="email" id="email" aria-required="true">
<!-- Option 2: Explicit instruction -->
<p>All fields marked with * are required.</p>
<label for="phone">Phone *</label>
<input type="tel" id="phone" aria-required="true">
Both work. Both tell the user before they commit. The aria-required attribute reinforces it programmatically for assistive tech.
And intention is the
difference between a form that
works and a form that
wastes everyone’s time
What doesn’t work: throwing a validation error after submit that says “Phone is required” when the user had no way of knowing that beforehand.
The Placeholder Trap, Expanded
I want to circle back to placeholders because they’re the most common offender I see in audits.
Designers love them because they create clean, minimal interfaces. Developers love them because they’re one attribute away from “done.” But placeholders have real problems:
- They vanish on input, leaving no persistent label
- They often fail contrast requirements (3:1 minimum)
- They can be mistaken for pre-filled data
- Screen reader support is inconsistent across implementations
- They increase cognitive load because the user has to remember what the field was asking for
Using a placeholder as your sole labeling mechanism is like writing someone’s name on a sticky note, handing them the note, and then snatching it away the moment they start reading. “You should have memorized it,” you say. “I gave it to you.”
That’s not how courtesy works.
Where Instructions Live Matters
A brief note on placement, because I see this fail in subtle ways.
Instructions should be near the field they relate to. If your form has a paragraph at the top that says “Please enter your date of birth as MM/DD/YYYY” and the date field is fourteen inputs later, that instruction is functionally useless to anyone who can’t hold it in working memory.
Better:
<label for="dob">Date of Birth</label>
<input type="text" id="dob" aria-describedby="dob-hint"> <span id="dob-hint">Format: MM/DD/YYYY</span>
Now the instruction is right where it’s needed, both visually and programmatically. aria-describedby ensures the screen reader announces it along with the field.
3.3.1 vs 3.3.2: Knowing the Difference
Since we just covered 3.3.1 (Error Identification), let me draw the line clearly:
3.3.2 is what you do before. Labels on fields. Instructions on format. Required indicators. You’re setting expectations.
3.3.1 is what you do after. Field-level error messages. Programmatic association. Clear description of what went wrong. You’re responding to mistakes.
Together, they form a complete cycle: tell people what you need, accept their input, and if something’s wrong, explain clearly what to fix. Skip either half and you’ve got a leaky bucket.
Tip: If there are multiple ways people enter information, like a phone number, let them enter it their way, then parse it behind the scenes into the format you need. For instance, one user could enter 301-555-1212, (301) 555-1212, +13015551212, and more. Each of these can be parsed with JavaScript without interfering in how the user interacts. This doesn’t negate the need to provide instructions, it just removes errors for users.
Reality Check
Every time someone encounters an unlabeled field or a missing instruction, they’re forced to guess. Guessing creates anxiety. Anxiety creates errors. Errors create abandonment.
For users with cognitive disabilities, this isn’t a minor inconvenience. It’s a cascade. They might not be able to recover from the first failed attempt. They might assume the form is broken. They might leave and never come back.
And for screen reader users, an unlabeled input isn’t just annoying—it’s a blackhole. The screen reader announces “Edit text” with no context. What text? For what purpose? They’re navigating blind in a way that goes beyond metaphor.
Labels and instructions are the most basic form of respect you can offer a user: telling them what you need before asking them to provide it.
Conclusion
Label your fields. Always. Not with placeholders. Not with floating labels that animate away. With persistent, visible, programmatically associated labels.
Add instructions when the expected input isn’t obvious. Format hints, required indicators, document preparation notes—whatever the user needs to succeed on the first try.
This isn’t hard. It’s just intentional. And intention is the difference between a form that works and a form that wastes everyone’s time.
Have some thoughts? Let’s discuss it on LinkedIn or Bluesky!
Discover more from Nat Tarnoff
Subscribe to get the latest posts sent to your email.

Comments are closed.