HTML5 Form Validation
TL;DR Replace your JS validation with HTML5 validation. It's easier than you think and gives you a ton of markup/styling control.
So you need to validate a form. You do the right thing and start with server-side validation. Then, if you're a good web-designer, you want to add in some client side validation so your users get feedback on whether they filled out the form correctly or not. If you're a really good web-designer you might even make that feedback instantaneous so the user is made aware that they entered a valid email address as soon as it becomes a valid email address.
You get the picture. It's not fun.
What if you could skip all that JS stuff and just validate with HTML5 attribute validators and CSS?
What is HTML5 Form Validation?
Basically you add attributes like
<input> fields and your browser does the rest.
Go ahead and try to submit the form in this CodePen demo with no content. Then try to submit it without a valid email address.
You may have noticed you can enter an email like
a@a. Clearly you want a real e-mail address. Let's make sure it matches the pattern of having a dot and 2 or 3 characters on the end. We can do this using the
pattern attribute and regex.
If you're tentative about learning regex you need to get over it. Regex is insanely powerful and in every type of programming you'll ever do. Regex101 is a great site for learning/testing/sharing patterns, and the fine folks at #regex on Freenode are incredibly helpful.
I suck at complicated regex so I'll Google for "email regex" (since I'm sure this has been solved already) and ended up finding one on regular-expressions.info. Here's our regex. If you read a little about the pattern you'll realize the author excluded lowercase matches because they expect you to use a case-insensitive flag. HTML5 input patterns don't accept flags so to get lowercase letters we need to add the uppercase and lowercase range (e.g.
A-Za-z). You can read exactly what each part of the pattern is doing in the right panel.
To make our validation errors throw something other than "Wrong format!" we can specify a
title attribute with a validation error.
Now try the email input in this demo.
Don't worry, you won't have to write crazy patterns for every input you have. Most of the time you just want to require something and make sure it's a certain type of data. For instance, a number over 5 might look like
<input type="number" min="5" required>.
Keep in mind that not all browsers support all the various validation attributes. For instance, FireFox doesn't support
pattern has pretty good support though so you can always replicate functionality.
minlength can be replicated with
3 is however long it needs to be.
If you can't find a pattern you had access to in your old JS library, you can probably find it by browsing their source code since ultimately the JS library is simply matching the exact same regex patterns as we are.
Wouldn't it be nice if our input would display some sort of indication when it was valid? There's a
:valid CSS selector for that. There's also an
:invalid selector. Check out the demo.
You'll notice the obvious caveat that invalid styles are showing up even when we haven't touched the input.
You might think about doing something like
:invalid:not(:empty) but it won't work because browsers are stupid and always consider form elements empty.
We could do some trickery with the new
:placeholder-shown pseudo-selector as shown in this demo, but browser support for
:placeholder-shown is horrible and there isn't a modern polyfill for it yet. Bummer.
Making it Gorgeous
My favorite part about this approach is you have complete CSS control over every bit of your form.
By pushing the
<span> under the
<input> we gain access to the adjacent sibling selector on our
.empty class and can create a faux placeholder that beautifully slides out of the way as soon as the input is no longer empty. Here's an example.
<span> being under the
empty class to the
<label> instead. Then it's just a matter of tweaking the CSS a bit. Here's an example doing it that way.
The validation classes also work on the
<form> element so you can really go nuts with style control.
There's no limit to what you can do with this approach. Some ideas:
- Add validation icons that fade in/out.
- Shake the input if the user unfocuses and it is invalid.
- Dim inputs as they're filled out correctly.
- Perfect in modern browsers and IE10+.
- IE9- doesn't support validaton pseudo selectors so you won't get the styling but the form still functions very nicely.
There's no way to style the validation messages. Browsers disabled the ability to style those. I don't necessarily think this is a bad thing since people will be used to these validation styles. In fact, that's probably why browsers decided to axe our access to them. Now they are standardized.
They're also out of the flow of the page so you don't have to worry about them pushing form elements around with their appearance.
If you absolutely need complete control over validation styles, this method might not be for you.
Leave a Comment
I'm excited to get some feedback on this and would love to see some cool validation styles/techniques.