I was shocked 😱 that placeholder text on an <input> (instead of a <label>) might TECHNICALLY PASS WCAG⁉ Do you agree?
Tags: a11y, html, webdev, discuss
Published: 2021-07-15 07:52:38

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)](https://www.w3.org/WAI/standards-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](https://dev.to/inhuofficial/w1y-d2s-a11y-h2e-to-be-so-b4y-c9d-a1d-i10e-38no) 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.](#mainarticle)

## 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](https://a11ysupport.io/tech/html/label_element) (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.

``` html
<label for="first-name">First Name</label>
<input id="first-name" type="text">
```
😢

<a name="mainarticle"></a>

## 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](https://www.w3.org/TR/WCAG22/) there are only 6 that seem to be applicable.

- [1.1.1 Non-text Context](#sc111)
- [1.3.1 Info and Relationships](#sc131)
- [2.4.6 Headings and Labels](#sc246)
- [2.5.3: Label in Name](#sc253) 
- [3.3.2 labels or instructions](#sc332)
- [4.1.2 Name, Role, Value](#sc412)

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

<a name="sc111"></a>
### [1.1.1 Non-text Context](https://www.w3.org/TR/UNDERSTANDING-WCAG20/text-equiv-all.html)
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!

<a name="sc131"></a>
### [1.3.1 Info and Relationships](https://www.w3.org/TR/UNDERSTANDING-WCAG20/content-structure-separation-programmatic.html)
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!

<a name="sc246"></a>
### [2.4.6 Headings and Labels](https://www.w3.org/WAI/WCAG21/Understanding/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!)

<a name="sc253"></a>
### [2.5.3: Label in Name](https://www.w3.org/WAI/WCAG21/Understanding/label-in-name.html) 
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](https://validator.w3.org/nu/#textarea)) is yes! The following is valid HTML!

``` html
<html lang="en">
  <head>
    <title>test</title>
  </head>
  <body>
    <form>
      <input placeholder="test">
    </form>
  </body>
</html>
```

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

<a name="sc332"></a>
### [3.3.2 labels or instructions](https://www.w3.org/WAI/WCAG21/Understanding/labels-or-instructions.html) 
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!

<a name="sc412"></a>
### [4.1.2 Name, Role, Value](https://www.w3.org/TR/UNDERSTANDING-WCAG20/ensure-compat-rsv.html)
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](#sc111). 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](#sc111), [1.3.1 Info and Relationships](#sc131) and [4.1.2 Name, Role, Value](#sc412) 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](https://www.w3.org/TR/2016/NOTE-WCAG20-TECHS-20161007/H44)

>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](#sc332) 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](https://www.w3.org/TR/WCAG20-TECHS/H65.html) 🙄 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](#sc111) 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 🤦‍♂️)  

> 3. 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!