DEV Community

Cover image for Fun with HTML5 form validation
Ross Angus
Ross Angus

Posted on

Fun with HTML5 form validation

The other day, I was messing about with HTML5 native form validation, and I unthinkingly included the following rule:

:invalid {
  border: solid 1px red;
}

I wanted to avoid listing out input, select and textarea in the CSS selector, so I figured I'd omit the tag names and save the bytes.

When I preview the page, I noticed a red border around the whole form. I realised that the :invalid pseudo-class could also be applied to other elements, to give the user feedback on how well they were filling out the form. Here's my proof-of-concept:

One of the limitations of HTML5 native form validation is that form fields are either :valid, or :invalid. There's not really a state for the user hasn't filled this in yet (note that the :empty pseudo-class describes a different concept). This means that if you go overboard on styling up the :invalid pseudo-class, the user will be presented with a lot of negative feedback, when they first land on your form. As it's hard enough to wrestle your user's private data from them, let's not add any more obsticles in the way.

I've split my example form into three elements, using fieldset elements. These will also take on a :valid or :invalid pseudo-class, as long as there's at least one form element inside them, with a required attribute.

This allows the form to give the user feedback as each chunk of the data is completed.

I've heavily abused the :before and :after elements, in order to provide thank you messages. Note that as input elements are self-closing, there isn't such a concept as :before or :after for them. If you wanted to add a thank you message which only appears after an individual form field has been completed, then the following markup pattern will help:

<p>
  <label for="my-input">Give me input</label>
  <input id="my-input" name="my-input" required>
  <span class="thanks"></span>
</p>

Then, the following CSS would give you a thank you message:

input:valid + .thanks {
  content: "Thank you for your input, human";
}

Note that putting messages into the content rule is a terrible idea. And as the aim of accessibility is to provide as close an experience as possible for all users, let's not encourage one set of users, while ignoring others.

Top comments (0)