DEV Community

Cover image for Modern form validation
Ovi Demetrian Jr
Ovi Demetrian Jr

Posted on

Modern form validation

Now that browsers have form validation built-in, we can better use related form field CSS properties to improve the user experience. Add the more modern has() CSS property to the mix and you can replace techniques that previously required Javascript with just a few lines of CSS code.

Add an asterisk to required fields

Using an asterisk next to a form field label is a common way to indicate that the field is required. But instead of adding it manually, it would make more sense to show the asterisk automatically based on whether the field itself is actually required. Here's how to do just that:

form div:has(label + *:required) label::after, form fieldset:has(*:required + label) legend::after {
  content: "*";
}
Enter fullscreen mode Exit fullscreen mode

A container is needed for each field and its corresponding label. For radio buttons and checkboxes, using fieldset acts as the container, and the field legend is used instead of label.

Highlight invalid fields

While the browser will prompt users if a required field is not filled out, or is filled out incorrectly, it does this only after the form is submitted. With the CSS below, this can be done on each text field, as the user is entering in their details.

form input:focus:invalid, form textarea:focus:invalid, form select:focus:invalid {
  border-color: #b91616;
  background-color: #f1e5e5;
}
Enter fullscreen mode Exit fullscreen mode

The field textbox or dropdown is shown with a dark red border and light red background when the user clicks into a field and the field doesn't meet the required criteria. It also works for field types like email that need a specific format for its contents. You can go further and use :focus:valid to indicate when a field does meet its requirements.

Change submit button state
As further indication of the state of form fields, you can change the submit button to make it look like it's disabled until all required fields are filled out, and are valid:

form:has(*:invalid) input[type="submit"] {
  background-color: #aaa;

  &:hover {
    background-color: #aaa;
  }
}
Enter fullscreen mode Exit fullscreen mode

This does not actually disable the button, it only changes its appearance. It still functions as a way to notify the user of which fields are missing information.

To see working examples of these techniques, along with other form field formatting options, check out our free Starter theme.

Top comments (4)

Collapse
 
rossangus profile image
Ross Angus

Great post, Ovi! I love the asterisk trick. While fooling about with this, I discovered that the invalid pseudo selector can also be checked on fieldset and form elements.

Also, I wonder if your clever submit button trick could stop the user from clicking with pointer-events? The form will still submit if they hit enter.

Collapse
 
ovidem profile image
Ovi Demetrian Jr

Thanks Ross! And thanks for those additional tips, I'll definitely look into adding them in!

Collapse
 
rossangus profile image
Ross Angus

The pointer-events trick might not be needed. I think forms won't submit anyway if the fields are invalid, but I haven't checked.

Thread Thread
 
ovidem profile image
Ovi Demetrian Jr

Yes, the form won't get submitted until the fields are all valid. I actually like that it only visually disables the submit button but it still technically works since it brings up remaining validation errors which can be helpful.