DEV Community

Frank van Eldijk-Smeding
Frank van Eldijk-Smeding

Posted on • Updated on • Originally published at

The what, why and how on labels

Today I want to take the chance to tell you about the importance of labels and what they have to offer us. So with this bite-sized post I’ll cover the following: what a label is, what a label does if you use them, how we can use/add labels and which other HTML elements should have a label.

So, what's a label to begin with?

Well, the <label> is a simple HTML element that holds a text value1, which explains something about the related input element. And that's basically it for our humble label element. So how could such a simple HTML element have such an impact? Let's find out together.

Why should we use labels?

Why we need to use labels, is to understand what they’ll do for us when we use them. So, what do we gain when we use a label? Well, when we’ve paired a label to an input field it does two things:

  1. Increases the interactive area of the associated input field. The browser does this for us when it sees a label paired with an input field. But what does it mean when the interactive area is increased? Well when the user clicks on the label it will instead focus on the associated input field. This improves the UX on mobile devices and for users with a physical disability (e.g. tremors).

  2. Screen readers are able to announce the name (the associated label) of an input field when it's focused. See the examples down below what the difference is with and without an associated label.

Without label

<input type="text" name="username" />
Enter fullscreen mode Exit fullscreen mode

This will say: "edit text blank" - on MacBook Voice Over

With label

<label for="username_input">Username:</label>
<input id="username_input" type="text" name="username"/>
Enter fullscreen mode Exit fullscreen mode

This will say: "Username, edit text" - on MacBook Voice Over

How could we add a label?

There are two approaches for adding a label. The first approach is called implicit and the second approach is called explicit. We'll cover implicit first and then I'll continue with explicit. And I’ll explain why the second approach is the recommended option.


With the implicit method we use the label as a wrapper/container. It doesn’t require anything else from us. Just put the input field inside and you’re done. You’ve added the label and associated it implicitly with an input field.

    <input type="text" name="email" />
Enter fullscreen mode Exit fullscreen mode

Let’s move on to the second approach.

Explicit (recommended)

With the explicit approach we don’t use the label as a wrapper/container. And we're not required to put it directly before the input field in the DOM* to make it work (which you’ll see in every example, even the one down below). So how could we tell HTML that the label we’re using is for specific input field? Through two special attributes: for & id.

<label for="email_input">Email:</label>
<input id="email_input" type="text" name="email"/>
Enter fullscreen mode Exit fullscreen mode

The label element has a for attribute that will have a certain value. The input element on their turn has an id attribute which also holds a certain value. You may have guessed it, without peeking at the example above, that both attributes need to have the same value. By using the same value in the for and the id attribute you'll explicitly associate the label to an input field.

So why is this the recommended approach? To put it simply, because of accessibility support2. At the moment it's not possible to select an input by its name (the associated label) through voice command (e.g. Voice Control from Apple). I've tested this myself on a MacBook with Safari and Voice Control. And it just didn't work, no matter how many times I've tried. I'll add a link down below for the current support results

Now we know how to use and associate a label with an input. But are we limited to just an input or are there more potential friends for our label? There sure are and they're grouped together under "labelable" fields.

Labelable, excuse me?

As a non English speaker, that word is just a mouthful for me. Moving on. So this term groups a list of elements together that should be paired with a label3. I won't go into it further details what each element does on its own.

Labelable fields:

  • button
  • inputs
  • meter
  • output
  • progress
  • select
  • textarea

The odd one in the list above is the button element. Even though it's considered a labelable element it should not be paired with a label. This is because the button already comes with a label, which is the text value inside the tags4. When using <input type="button" value="Sign up"/> the label comes from it's value attribute.

Credit goes to InHuOfficial for pointing out that I've missed this in the original post.


  • When labels are used screen readers are able to do their work and assist their users
  • Labels increase the interactive area for input fields which improves the user experience
  • Using labels explicitly is the recommended option when pairing up with a labelable element
  • Labels used implicitly lack support for voice commands

In the next bite-sized blog we’re going to learn what to do when we can’t show a label visually. For whatever reason that might be.


  1. Read more - MDN Label documentation 

  2. Read more - Lacking support for implicit labels 

  3. Read more - HTML labelable elements 

  4. Read more - Labeling buttons 

Top comments (6)

grahamthedev profile image
GrahamTheDev • Edited

Great and detailed article! ❤ and 🦄 from me!

One thing to note that may not be clear, although a <button> is labelable, the label should not be set with the <label> element (the text inside the button is the label).

Similarly if for some reason you are using <input type="button"> then the value attribute is treated as the label and a <label> element should not be used.

Using a <label> can actually make accessibility worse for <button> elements!

Given the subject of the post being focused on the <label> element I thought that was an important distinction.

beingfrankly profile image
Frank van Eldijk-Smeding

Thanks @inhuofficial for the great reply! I'll change the post to include this as well, totally missed this while I was writing the post! :-)

grahamthedev profile image
GrahamTheDev • Edited

I could tell from the accuracy it was more of an unintended implication than anything else. One of the most accurate and complete articles I have read on labels as they all forget voice etc.

I look forward to the next instalment!

peetboy profile image

I don't like the binding with id prop. It basically push you to use id even when you don't need it. Good example is repeating components with the same input fields. In such case if you want to use option #2 you have to define id for input. But since this input is showing on UI multiple time it should have unique id therefore you need to make it dynamic and incorporate index into the id.

beingfrankly profile image
Frank van Eldijk-Smeding • Edited

Hi peetboy,

Thanks for replying! I'm curious about a couple things and since I want to learn I hope you can help me out here. Could you tell me more about which framework you're using? And what do you usually do with repeating components? Do you use the implicit approach of using labels? And what part do you dislike about the binding of id prop?

I think that using the index combined with a certain prefix would be a solid solution to get a unique ID for the input and label, so you should be able to go with the explicit approach :-)

peetboy profile image

Hi Frank,
we are using Vue + BootstrapVue and the most use cases with repeated components are UI forms (banking sector, regulatory forms) where user wants to see all data on the screen. We have created own input components (or I would say wrappers around bootstrap components) and the labels were with explicit approach hence yes, we had to combine index with the ID to get unique identifiers. This of course added a complexity (although small) on other places which we did not expect. But still it doesn't look OK to me that we have to generate IDs just because of label or otherwise we would not need them. There is no need to have ID in Vue app and if you need specifically work with some DOM element, you can use refs instead.