Blog

An Opinionated Developer’s Guide To Form Validation Best Practices

Updated on: 
February 23, 2023
by
Colin Gray
Colin Gray

Learn more from an Opinionated Developer – co-founder and board member Colin Gray takes a deep dive into important software engineering topics of interest. In this post, Colin shares his wisdom on the guaranteed only best way to do form validation (in his opinion, of course.)  

The purpose of form validation is fairly straightforward. It's the set of mechanisms by which a web form checks if the information provided by a user is correct and valid. The process on how to do form validation is less cut and dry.

1. Prompts

Form validation should first aim to be as accommodating as possible for different forms of input based on particular data types. In doing so, sensible labels and text inputs should have a placeholder that shows an example. 

Labels should be tagged with the <label for="input-id"> element so that clicking on the label selects the tag (or checks/unchecks a checkbox). For accessibility compliance, screen readers will read the label when the user selects the input. 

<label for="signup_email">Email</label>

<input type="email" id="signup_email" placeholder="[email protected]" />

Using the placeholder to hold the title isn't the worst thing you can do. While it saves space, which can be helpful on mobile, it's not preferred. One advantage of always having a label is you have a place to show a related error message. 

*Note: Email is required (e.g. [email protected])

2. Inputs

There are a few major considerations when it comes to inputs. These include

  • Input types (and validation)
  • Localization/internationalization (l10n/i18n)
  • Usability

Input Types

First, check your input types. E-mail should have <input type="email">, numbers should have <input type="number">. 

That said, there are some input types that should actually be avoided. For instance, "date" is notoriously poor on Apple Safari (example screenshot). You would do better with the classic three inputs, but in what order?! 

Screenshot of the date input default UI on Apple Safari
Date input default UI on Apple Safari

When it comes to validation, less is often more. Email address validation is famously complex - the best you can do is to verify there's exactly one @, followed by something that looks like a domain. I can't tell you how many times my thegray.company email address gets rejected by email validators that are using a fixed - and outdated! - list of top-level domains. Or password validators that don't support long pass phrases.

Localization/Internationalization

Here's where localization (l10n) comes in. This is distinct from internationalization (18n). i18n says that "month" in Japanese is "月", but localization says that Japanese order their dates "year, month, day". This is next-level good behavior, and to be honest with dates, I always put them in the order year-month-day. 

This is because very few countries/cultures (none that I know of) will be confused by that, as opposed to the fractious month-day-year vs day-month-year divide (or you could live in Canada where they use both - not kidding). It's a shame the default controls for <input type=date /> are so lackluster. If they were decent, we could trust the browser to choose a good date picker for the locale. 

No matter the order, please use a drop-down for month and year, and an open input for day. No one will confuse which is which, guaranteed, and selecting from a drop-down with more than ~25 items is tedious. Just validate that it's a number. 

Usability

My next hill to die on is addresses. It is intuitive to make address inputs in the same order that we put them on envelopes.

Intuitive, but... not helpful.

Put the country first, then the postal code, and use that information to auto-fill the other inputs. 

And did you notice I said, "put country first"!? If you are designing a credit card entry, and validate that "postal code" is "a United States formatted zip code", you need to get out more. 

News flash: not all countries are the United States. Honestly, if you're validating credit card inputs on the client, you're doing it wrong. Let the credit card company deal with it (send it to them for validation). This carries over to all third-party services – do not hardcode their validation rules in your app. 

You should be parsing their error messages and forwarding them to the user. If the service has terrible or contains no error messages - is it a bank? Banks are the worst - I would put validators *after* the attempt to submit the data as-is. What I mean is: assume success, and on error run your own validators. So if the service changes what is "valid" your error messages will be wrong but your user won't be blocked. 

3. Error Messages

The most important word here is Actionable. Breaking our task down further, our error messages should:

  • Timing: appears when the user has shown their intent to submit the form (not sooner)
  • Visibility: appears everywhere the user might look 
  • Actionable: describe what action to take to resolve the error

Timing

The first bullet is easy: when the user first arrives, let them move freely around the form. Maybe they're gaining context, maybe they copied some text into their clipboard and want to paste that into your “comment” form before entering their email. Who knows!? And you shouldn’t care. Just wait until they press submit before showing the errors. When do you hide the errors? 

I’ll give you a choice: when they press submit again, or continuously while they are editing. e.g. The “Email is required” message should go away when they enter an email – but then do you also show “Valid email is required” during this editing? Ideally not, so… waiting until they press submit is usually simple, and simple is usually best.

Visibility

Next, visibility. You have more options here, depending on the complexity of your form. If you have a survey with 30 questions, you don’t want to summarize 30 validation errors at the top of the page. 

Actionable

You should have a generic “there was a problem” message at the top and then highlight the sections that were incorrect, along with an error message. If your form is doing client-side validation, make sure to show a “there was a problem” message near the submit button! Otherwise, your user will have no way to know why the button isn’t working.

If you have a short form, like email and password entry, your users would be well served by grouping the error messages at the top, because they can probably view everything at a glance.

I’m not a huge fan of “automatically scroll to errors”, but it beats the pants off of a page that doesn’t do a good job informing the user (1) that there was a problem and (2) where the problem is. 

I prefer, instead, clickable error messages that take you to the appropriate field.

Thanks for joining us alongside an Opinionated Developer. Reach out to Gray Dot Company if you need support with Strategy + Tech + Data. 

More from Colin Gray

Work With Us
We’ll help craft, teach, and carry out SEO roadmaps that check all the boxes.
CONNECT THE DOTS WITH US