We've got a problem.

HTML forms are the life blood of data on the web. They've allowed us to post custom data around our fantastic online world since day one of the mainstream world wide web revolution. Yet they've got an underlying flaw that the majority of web creators simply take 'as-is' and use without question; the for attribute.

  <form>
    <label for="this-field">A label for this-field</label>
    <input type="text" name="this-field" id="this-field">
</form>

It looks harmless enough doesn't it?
It's simply telling the browser that it is linked to the input where the id value matches the labels for value.

Let's introduce another label and input pair then tell me what you think.

  <form>
    <label for="this-field">A label for this-field</label>
        <label for="another-field">A label for another-field</label>
        <input type="text" name="another-field" id="another-field">
    <input type="text" name="this-field" id="another-field">
</form>

Gah! It's horrible. Take it away.
This second example is still perfectly valid and that's the problem with the for attribute. It allows you to place your label anywhere within your body, it will still pass validation and apparently it's still semantically correct - but it isn't, we can see it isn't. We can see our second label and input set dividing the logical progression of the first set. There's no way a label and input set separated by other meaningful content should be semantic so lets stop ignoring the obvious and address it. Please. It's about time.

Luckily, I'm sure you're aware you don't need to use the for attribute at all. Woohoo!

  <form>
    <label>
        A label for this-field
        <input type="text" name="this-field">
    </label>

    <label>
        A label for another-field
        <input type="text" name="another-field">
    </label>
</form>

HTML allows us to use the label element as the parent container for the label text AND the input the label is instructing. This doesn't sit 100% right with me either but looking at the above example it is the lesser of two evils. It allows us to drop both the for attribute from the label and the corresponding id attribute from the input. Everything is compartmented together so theres no confusion and no interjected, spaghetti, illogical markup.

In my opinion an input should always be immediately preceded or proceeded by its corresponding label. Mic drop

What we really need is to abolish the for attribute to the archives of time and introduce a new element. Maybe a form <set> element? Something that allows us to markup our forms coherently where the boundaries for our form elements are clear. Oh, and make it block-level by default - Cheers!

  <form>
    <set>
        <label>A label for this-field</label>
        <input type="text" name="this-field">
    </set>

    <set>
        <label>A label for another-field</label>
        <input type="text" name="another-field">
    </set>
</form>

I don't know about you but that feels perfect. It's almost as if the new element belongs there already; problem solved.

Maybe one day my dream of a more rigid form markup will come true, one where we get penalized if we try to hack around the rules of engagement.


It shouldn't be there

"But what about my CSS only burger navigation revealer?" I hear you cry.

Although it is very cool we can do this, it is still a hack made possible by the for attributes flaw. It shouldn't be possible to use a checkbox input and a label in this manner, let alone outside of the form element. In my opinion they should always be contained within a form and always have meaning.
If you look at the above pen with no styling you will see a floating checkbox at the top of page with no semantic value. It shouldn't be there.

It's the job of a good developer to keep the dry experience (no CSS or JS) completely relevant, legible and semantic.
It all boils down to whether you care enough about semantics and accessibility. If you do then you could achieve the same result as the pen above by progressively enhancing with a little bit of javascript.


Conclusion

So to round-up this little rant:

  • The form element and it's child elements should be more strict in their usage.
  • We need to stop using the for attribute.
  • We need a new block-level form element introduced to contain an input and it's corresponding label.
  • We need to prioritize semantics and accessibility over cool hacks that shouldn't be possible.

I'd love to hear your thoughts.
Please do throw some spanners in my works. You could convince me I'm wrong. I'd even thank you for it!


You can also find me on: Twitter


570 0 0