DEV Community

loading...
Cover image for I was shocked 😱 that placeholder text on an <input> (instead of a <label>) might TECHNICALLY PASS WCAG⁉ Do you agree?

I was shocked 😱 that placeholder text on an <input> (instead of a <label>) might TECHNICALLY PASS WCAG⁉ Do you agree?

InHuOfficial
Specialising in accessibility and website load speed / performance. If you have a question about [accessibility] or [page-speed-insights] ask away and I will help any way I can!
・10 min read

Does a placeholder on an <input> without a <label> pass WCAG? From my assessment I would say technically yes...but please don't do it!

For those of you who like deep dives and want to see how the hell I, the guy who prattles on about accessibility all the time, came to that conclusion...strap in!


Important Information!

Oh and a really important point here before we start: I am playing "devil's advocate" here, it is clear that if we apply common sense WCAG does not recommend placeholder attributes as a suitable alternative to <label>s. I am just being pedantic!

You should always use a <label> element, this article is purely a thought experiment, not a recommendation!


I am about to get heavily into Web Content Accessibility Guidelines (WCAG) and show (as far as I am aware) that because of the over complicated, edge case, loop the loops that exist in WCAG , answering the simplest accessibility question of them all is far from simple.

For those of you who missed it, I did have an "angry rant" about WCAG in the past you might enjoy, if you like sarcasm and swearing that is!

In fact that post was what reminded me about this and the Stack Overflow answer I gave on the same subject (which is the inspiration for this post)!

Anyway, lets start with an important message! If you already know you should always have a visible, properly associated label then you can skip to the main content.

Before we start

While I may land on "technically yes" at the end of this article, I want to warn you that having a placeholder as a label is not accessible.

Just because it might "pass" WCAG AA guidance doesn't mean you should do it.

Visible labels (that are properly associated with an input) have hundreds of benefits over a placeholder:-

  • people with anxiety disorders need visible labels to stop them having to keep deleting their input to see your placeholder and check they filled in the correct field.
  • people with poor vision may be using a screen magnifier to zoom to part of the page, it is easy to lose your position and a label lets them know they are still filling in the correct field / where they are in the form
  • people with very poor vision (as well as people with learning impairments, people from other countries trying to improve understanding etc.) may use a screen reader - a properly associated label is important for them!
  • people with no disabilities will find your form easier to use and will be more likely to fill it in, so even if you don't care about other people your conversion rate will improve and that will benefit you.

Accessible input example

Notice how I don't use implicit labels (wrapping the input in the label).

While it is far neater, semantically correct etc. there is an unfortunate failing in voice software.

Dragon Naturally Speaking and Apple Voice control don't work properly with implicit labels (no I am not joking!).

So you should probably stay old school with your labels and use the for attribute on your labels to explicitly associate the label with the input.

<label for="first-name">First Name</label>
<input id="first-name" type="text">
Enter fullscreen mode Exit fullscreen mode

😢

Anyway - to the question - does placeholder text on an input pass WCAG?

For the purposes of this article I am talking about standard <input> and <textarea> elements.

Checkboxes, <select> etc. etc. must have visible labels.

But as placeholder attributes appear on standard <input type="text"> elements and <textarea> elements that is what I am focusing on here.

So which WCAG rules apply?

Out of the 80+ Success Criterion (rules) in WCAG 2.2 there are only 6 that seem to be applicable.

Lets tackle each one and see whether any of them give us an answer!

1.1.1 Non-text Context

The general idea of this Success Criterion is that anything that is not text (images, controls etc.) should have an alternative way of describing those items programatically to assistive technology. For example alt attributes on images describe an image to assistive technology such as screen readers.

So a key sentence in this Success Criterion is:

Controls, Input: If non-text content is a control or accepts user input, then it has a name that describes its purpose.

OK, so that means we need to know what is a "name" in the context of WCAG.

Name in the context of WCAG

text by which software can identify a component within Web content to the user

Source: https://www.w3.org/TR/UNDERSTANDING-WCAG20/text-equiv-all.html#namedef

Well that is super useful, now we need to know how software can identify a component.

Luckily we have that covered too (and specifically for <input> elements which is super helpful!)

5.1.1 input type="text", input type="password", input type="search", input type="tel", input type="email", input type="url" and textarea Element Accessible Name Computation

  1. If the control has an aria-label or an aria-labelledby attribute the accessible name is to be calculated using the algorithm defined in Accessible Name and Description: Computation and API Mappings 1.1.
  2. Otherwise use the associated label element(s) accessible name(s) - if more than one label is associated; concatenate by DOM order, delimited by spaces.
  3. If the accessible name is still empty, then: use the control's title attribute.
  4. Otherwise use the control's placeholder attribute.
  5. If none of the above yield a usable text string there is no accessible name.

Source: https://www.w3.org/TR/html-aam-1.0/#input-type-text-input-type-password-input-type-search-input-type-tel-input-type-email-input-type-url-and-textarea-element-accessible-name-computation

Right, that is a lot to digest but point 4 is the one that is relevant to this article, the placeholder attribute can be used to calculate the name for an element.

So does 1.1.1 Non-text Context contain anything that requires a visible label?

Nope!

If you read the whole page there is not one specific mention of a <label> element needing to be used on a form control.

So far, we have no answer 😢.

Maybe Info and Relationships will help us!

1.3.1 Info and Relationships

The general idea of this Success Criterion is that structure and relationships can be programatically determined and don't rely solely on visual cues. (For example if you just used <div> elements for your whole application there is no way for a screen reader to work out what information is related as <div> elements have no semantic meaning.)

Checking 1.3.1 - although it mentions labels, it does not specifically mention the <label> element anywhere. It also states that it is a "judgement call" as to whether relationships should be programmatically determined or presented in text.

There may also be cases where it may be a judgment call as to whether the relationships should be programmatically determined or be presented in text. However, when technologies support programmatic relationships, it is strongly encouraged that information and relationships be programmatically determined rather than described in text.

Anyway, this Criterion is more likely to cover "does a label have to be associated with an input"...which worryingly may also be questionable given "strongly encouraged" is the wording here.

Anyway, that isn't the point of this article. As it stands, will still have no answer either way!

2.4.6 Headings and Labels

Rather than spend too much time here we get an early answer as to whether this Success Criterion is relevant:

This Success Criterion does not require headings or labels. This Success Criterion requires that if headings or labels are provided, they be descriptive.

Well as we are arguing that we might not need labels this obviously won't apply!

So as this point isn't relevant, lets try SC 2.5.3 Label in name (sounds promising!)

2.5.3: Label in Name

The idea behind this Success Criterion is that if there is a label with text, then that text can be accessed programatically (so you can't use just an image of text for example without an alt attribute...but if you are using images of text for labels you have bigger problems! 🤣)

Well unfortunately WCAG ties itself in knots again here:

Note that placeholder text within an input field is not considered an appropriate means of providing a label. The HTML5 specification states The placeholder attribute should not be used as an alternative to a <label>. However, it is worth noting that "label" in that HTML5 statement is in code brackets and links to the label element. For the purposes of this Label in Name Success Criterion, "label" is not used in such a programmatic sense but is simply referring to a text string in close visual proximity to a component. As such, in the absence of any other nearby text string (as described in the preceding list), if an input contains placeholder text, such text may be a candidate for Label in Name. This is supported both through the accessible name calculation (discussed later) and from the practical sense that where a visible label is not otherwise provided, it is likely that a speech-input user may attempt to use the placeholder text value as a means of interacting with the input.

So this Success Criterion still doesn't give us an answer, if anything it actually looks like it is supporting placeholder text as a viable (sub-optimal and not recommended) alternative to a properly associated <label>.

However there is another thing to note here.

The HTML5 specification states The placeholder attribute should not be used as an alternative to a <label>.]

Now that should persuade you that a visible and properly associated label is essential.

But it says it shouldn't be used, not that it cannot be used. SO the question is...

Is an input with just a placeholder attribute valid HTML?

Well we have the W3C Validator to check this against.

So is an <input> with a placeholder valid HTML? Well the answer (according to the W3C validator) is yes! The following is valid HTML!

<html lang="en">
  <head>
    <title>test</title>
  </head>
  <body>
    <form>
      <input placeholder="test">
    </form>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

I am growing weary now, but "labels or instructions"...this is it, this is all about labelling things!

3.3.2 labels or instructions

This Success Criterion is all about authors providing labels or instructions in forms.

However out hopes are destroyed almost instantly:

This Success Criterion does not require that labels or instructions be correctly marked up, identified, or associated with their respective controls.

Our last hope, Name, Role, Value....come on 4.1.2...you can do it!

4.1.2 Name, Role, Value

This Success Criterion is to ensure that important information about all elements on a page can be programatically determined.

We already covered this in 1.1.1 Non-text Context. A placeholder attribute is considered acceptable for name computations and therefore we pass this Success Criterion too!

One final swing of the sword, surely there is something that states a label must always be visible!

As placeholder attributes disappear once data is entered perhaps the answer is now looking at it from a code standards standpoint but purely from a perspective of a label having to be visible?

Interestingly you do not have to have a visible label for 1.1.1 Non-text Context, 1.3.1 Info and Relationships and 4.1.2 Name, Role, Value so we can't use that argument as to needing an actual <label>.

Taken from H44: Using label elements to associate text labels with form controls

This technique (associating a label with an input) is sufficient for Success Criteria 1.1.1, 1.3.1 and 4.1.2 whether or not the label element is visible. That is, it may be hidden using CSS.

With that being said the next sentence says...

However, for Success Criterion 3.3.2, the label element must be visible since it provides assistance to all users who need help understanding the purpose of the field.

But in 3.3.2 labels or instructions although it has to be visible, it doesn't have to be correctly marked up (remember, I did say it a long time ago!).

The loops continue!

So there is all the relevant information I could find in WCAG and the outcome is still fuzzy, but with that being said I do have a conclusion for you!

Conclusion

Nowhere in WCAG does it explicitly state that a placeholder cannot be used as a label.

WCAG also states that a title can be used to label an input 🙄 and that is worse than a placeholder as it is completely inaccessible to keyboard users!

We also covered this 1.1.1 Non-text Context when we were discussing accessible name computations.

You may have missed it as we were focused on point 4 about placeholders but point 3 says the title attribute can be used! (yes, title attributes are used before placeholder attributes to calculate the accessible name...it shows the age of the documents as title attributes are useless nowadays with touch devices and useless to keyboard users 🤦‍♂️)

  1. If the accessible name is still empty, then: use the control's title attribute.

Am I 100% certain?

Well WCAG is hundreds of thousands of words so it is possible I have missed a key sentence somewhere that would tie it all together.

But from what I have read I believe (very surprisingly!!) that it is valid under WCAG 2.1 to only have a placeholder on an <input> if we are going by "the letter of the law".

Obviously as I stated several times DO NOT USE A PLACEHOLDER ONLY ON AN INPUT as it is not accessible to a lot of users rely on visible labels.

For example: People with anxiety disorders or learning difficulties really hate inputs with placeholder attributes as labels. This is because the label disappears when they type so they can't check they have filled the correct field in without deleting everything.

Also some screen reader and browser combinations do not work with them.

And above all - if you can somehow find a definitive answer to this question within WCAG then please let me know in the comments. While this has been a fun article to write I would hope that somewhere there is a line of text I have missed!

Discussion (18)

Collapse
lexlohr profile image
Alex Lohr

In my personal a11y rules, placeholders should only ever contain the default values of optional fields. That's the only place they make perfect sense. Otherwise, just use a label. There is one exception, though: an <input type="search" placeholder="Search&hellip;">, which is already rather accessible on its own (though it may profit from a separate button).

Collapse
codingsafari profile image
Nico Braun

default value should be a real value and not a placeholder, imo. Otherwise its kinda confusing.

Collapse
lexlohr profile image
Alex Lohr

If you enter a field with a default value in it, your input could be appended, which might be unexpected behavior and even more confusing than a placeholder that vanishes if you enter something else.

Thread Thread
inhuofficial profile image
InHuOfficial Author • Edited

I think @codingsafari meant you should use a real world example of valid input as your placeholder text.

I would say you are both right depending on the circumstances.

So for a search box "Search...." might be applicable (a generic instruction) whereas for a "first name" field it might be better to have "e.g. Mike, Sarah etc." as the placeholder (providing an example of valid input).

For a normal input field, the following is "the ideal" Markup

<label for="dob">Your Date of Birth</label>
<p id="dob-instructions">Please enter your Date of birth in the format DD/MM/YYYY</p>
<input id="dob" type="text" aria-describedby="dob-instructions" placeholder="e.g. 17/01/1994">
Enter fullscreen mode Exit fullscreen mode

As the instructions are visible and clear in the <p>, which is correctly read after the label for screen readers using aria-describedby and we have linked the label to the input correctly (so you can click it to focus the input and screen readers get the info) the placeholder is ideal for an example of valid input.

Also as I said in the article, using old school for attributes on the label is more robust due to issues with voice control software and implicit (wrapped) labels!

Collapse
inhuofficial profile image
InHuOfficial Author

Yeah search is one of those weird exceptions to a visible label, but even then aria-label="search the site" is advised.

Actually a better way is to do it "properly" and do:

<form role="search">
   <!-- your input, submit button (preferable, depending on implementation though) and a visually hidden label using CSS to make it accessible to screen readers but invisible visually -->
</form>
Enter fullscreen mode Exit fullscreen mode

Or use the floating label technique (where the label moves up when the field is focused) if space / design allows.

Collapse
inhuofficial profile image
InHuOfficial Author

I seriously do hope that somebody can find the missing sentence that explicitly states that you must not use a placeholder and must have a <label>.

If you do let me know and I will update the article!

Collapse
codingsafari profile image
Nico Braun

Its not one vs the other. In fact a good input should have both.

Labels are always visible not just when the input is empty. They represent the "key" of the key-value-pair.

Placeholder can provide useful example inputs. They represents the "value" of the key-value-pair.

These 2 things dont have the same meaning and impact.

I dont think trying to use placeholder as label is very accsible in its nature. If its explicity statet in the spec or not.

Collapse
inhuofficial profile image
InHuOfficial Author

I have added a massive disclaimer just so people don't get the wrong idea. I realised that I didn't cover that you shouldn't do this until a few paragraphs in and if skim reading you might miss it.

It now has pride of place at the start of the article so I hope that clarifies! Thank you for pointing it out!

Collapse
inhuofficial profile image
InHuOfficial Author

Sorry I really must make my article more clear, this is purely about technicalities and not whether you should or shouldn’t do it.

You should always have a label and unless completely necessary it should always be visible (I.e. an actual label element properly associated with the input)

Do not just use a placeholder alone!!!!!!!

Collapse
auroratide profile image
Timothy Foster

This is pretty funny ( :

I did find that the HTML Living Standard explicitly says the placeholder attribute should not be used as an alternative to a label, but that's not WCAG, so yeah ^^'

Collapse
inhuofficial profile image
InHuOfficial Author • Edited

Yes and the HTML spec is actually referenced in WCAG on that exact point. But then it goes on to say that a label in that Success Criterion is not the same as a <label> and ruins it! 🤣

I covered that in 2.5.3 as it amazed me that it was so close to being definitive and then back tracked on it!

Collapse
alohci profile image
Nicholas Stimpson

I think you're dismissing 3.3.2 incorrectly. It says that the label needs to be provided, it just doesn't require that it be marked up correctly, because that requirement is elsewhere. And a placeholder cannot provide a label because it is unavailable once the user starts entering data into the field.

Collapse
inhuofficial profile image
InHuOfficial Author • Edited

It doesn't actually state a label must be provided though, it states labels or instructions.

There is no real definition of an instruction so a placeholder could do.

Also when it points you to 1.3.1 that only wants a label to be programatically determinable (which we established a placeholder is).

It also doesn't state a label must always be visible.

I know I am being pedantic and silly but I still find it amazing that I can even argue the point in the first place!

And if we go down this route focusing on 3.3.2 as the centre of our argument then

<p>First Name</p>
<input type="text" placeholder="First Name">
Enter fullscreen mode Exit fullscreen mode

could pass all criteria (I would have to have a think about it as info and relationships might now make the above a fail), and that is nearly as bad!

Collapse
jmau111 profile image
J.

It does not pass most automatic tests and validators.

Collapse
inhuofficial profile image
InHuOfficial Author • Edited

No and I would hope it wouldn't!

But that isn't the point of the article.

For example what rule are the accessibility validators and testers citing when it says it fails? I can almost guarantee they point to one of the 6 Success Criterion I mentioned.

It is more of a thought experiment / critique than something you should actually be doing! (and I really I hope I made that clear otherwise I am adding to the problem instead of just writing an interesting (to me) article🤣 )

It can't be that difficult to write "an <input> should always have a correctly associated <label> or at the very least make use of WAI-ARIA to label the input. For example using either aria-label or aria-labelledby would be sufficient even if a visible and native <label> is strongly encouraged and preferred."

Collapse
jmau111 profile image
J.

The post makes sense, at least for me, the why is not 100 % clear in the specs.

Collapse
link2twenty profile image
Andrew Bone

Problem solved, right? 🙃

Collapse
inhuofficial profile image
InHuOfficial Author

Well if you are going to use a label that is cheating!

I both love (for the technicality part of it) and hate this at the same time (as somebody is bound to think this is a good idea lol).

I think this also technically passes, even if I do hate it so so much and want to burn it with 🔥