Give your Forms some Form

JP de Vries
Frontend Weekly
Published in
5 min readApr 12, 2017

The year is 2017 and for better or worse JavaScript is everywhere. Tools like React allow us to virtualize our documents, making turning web pages into web applications more approachable than ever. But sometimes what we can do with these tools conflicts with what we should do with them.

As Web Developers we should remind ourselves what the “web” fragment of our job title stands for. The “web” stands for the “world wide web”. Until we make contact with aliens in a distant galaxy, and also have to start considering their accessibility needs, world wide is as inclusive as it gets.

Tim Berners-Lee reminds the world that the web is for everyone — 2012 Summer Olympic Games.

HTML Forms are a fundamental feature of the web and give us a reliable way to accept user input. To get that far though, we need to make sure all our users can input and submit data in the first place. Ideally, our initial HTML layer includes forms that use the action attribute so that even if JavaScript is disabled, or breaks, our forms remain performant.

Progressive Enhancement attracts best practices. Since we have to use HTML forms in our initial HTML layer for it to work at all — they are already there. Easy peazy. Conversely, the JavaScript–first patterns often found in Single Page Applications (SPAs) may attract poor practices. These tools are shiny and new but they also make it too easy for us to overlook the twenty years of web standards that preface them. For example consider this React component:

Makes sense right? We can type a search term in the input, click the search button, and our props.onSubmit method is called. There are a few issues here:

  • not all users click
  • our submit “button” is only accessible to sighted mouse users
  • Our form is not a form, it is a div
  • our input is not labeled
  • incorrect usage of placeholder
  • we are not leveraging the Form Validation API

Here’s another pattern I’ve been noticing lately:

Short and sweet right? Well, for sighted keyboard users yes it is. Issues with this pattern include:

  • There is no submit button
  • Our input is not labeled
  • Our form is not compatible with user agents that may submit forms in any way other than dispatching a keyDown press of the Enter key
  • Our form is not a form, it is a div
  • incorrect usage of placeholder
  • we are not leveraging the Form Validation API

So let’s give our form some form:

We’ve changed our div.search to form[role="search"]. Our form will now be added to the Accessibility Tree as a standard form and bring all the magic of web standards, such as the HTML5 Form Validation API, along with it in addition to hinting to assistive technology that this is a search component. Notice the required attribute we added. This indicates to the browser that if the input is left blank the Form submit event should not fire, and instead alert the user they must input a valid search term. We've described our input with a standard label and are correctly using the placeholder attribute. Placeholder is meant to offer an example of a valid entry to an input; not to describe an input. So for example:

We are also listening to the native form submit event, rather than making assumptions on how that form may be submitted. This technique is immeasurably more accessible as it lets the user agent be in charge of how a form is submitted. We’ve added a standard submit button. Our submit button is clever without us having to add any code to make it so. Whether it is clicked, or the enter key is pressed with the button focused, it will submit our form for us.

Visually Hiding Form Labels

We should be proud of our semantic form, <label> and all. But our Art Director might not be so pleased. Perhaps the visual label conflicts with their design. That is OK. We can visually hide the label without removing it from the accessibility tree. Everybody wins. Add this CSS snippet to your stylesheet which will give you a .visually-hidden class. Now add that class to your <label>.

Alternatively to the .visually-hidden pattern you can label the input using the aria-label attribute:

Meaningful Placeholder Attributes

Earlier we covered that the placeholder attribute is meant to offer a suggestion, an example of a valid entry, not describe an input:

Kittens. It should always be kittens.

Whenever we use a tool, we should ask ourselves “What unique capabilities does this tool have? Am I using these capabilities to their full potential?” When I asked myself this about React, I realized it is particularly excellent at updating the DOM for us. This means that, rather than using a static placeholder value like “kittens” we could use a dynamic value. We could ensure that the placeholder attribute of our Filter component is always suggesting an example of a valid entry that would actually yield results. Take the Eureka Media Browser for example, its filter component will display a placeholder according to the following algorithm:

  • every X seconds and/or when updating the current directory, pick a random media item from the current directory
  • pick a random property of the media item, such as filename or file size
  • set placeholder to this random property of a random media item

So the input component actually updates its placeholder attribute on a setInterval. This educates the user by presenting them with a variety of valid entries they could use.

Eureka Media Browser cycling through valid entries that would yield results for filtering the current directory

Typeahead Hints with <datalist>

HTML 5.2 adds the <datalist> element which is used by modern browsers to create pure HTML typeahead components. An<input> decorated with <datalist> is kind of like if <input> and <select> got together and had a baby. Users can type whatever they want, but they can also choose from a list of options.

Here is an example of using <datalist> to decorate an input with React. Notice we leverage the virtual nature of React to bind our <datalist> options to our state. Visit the interactive example on Glitch.

Conclusion

With great power, the VirtualDOM makes poor practices and best practices alike more feasible. And with great power comes the responsibilities of architecting a web for everyone.

--

--