How to Make Floating Input Labels With HTML5 Validation

TL;DR Replace your JavaScript validation with HTML5 validation. It’s easier than you think, and gives you a ton of markup and styling control. Try this demo:

What We’re Doing Here

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 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 reach for your favorite jQuery library. Perhaps you’re even cool enough to use a vanilla JavaScript library.

You add some extra markup. Re-style some stuff… add some JavaScript validation rules. Connect the JavaScript to the server via AJAX. Bash your head against the keyboard a few times because you haven’t done this in a couple of months and have to look up exactly how that new JavaScript validation library does things… And so on.

You get the picture. It’s not fun.

What if you could skip all that JavaScript stuff and just validate with HTML5 attribute validators and CSS?

What is HTML5 Form Validation?

In rough terms: you add attributes like required or type="email" to <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:

Regex Patterns

You may have noticed you can enter an email like a@a. Clearly you want a real e-mail address, so by specifying a precise pattern that our data must match, we can validate what’s entered. Let’s make sure it matches the pattern of having a dot and two or three characters at 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.

I’m dreadful at complicated regex so I Googled 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 on regex101.com (a very useful resource for testing your regular expressions).

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, like this:

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’ll 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 minlength. pattern has pretty good support though, so you can always replicate functionality. minlength can be replicated with pattern=".{3,}" where 3 is however long it needs to be.

If you can’t find a pattern you had access to in your old JavaScript library, you can probably find it by browsing their source code, since ultimately the JavaScript library is matching the exact same regex patterns as we are.

Instant Feedback

Wouldn’t it be nice if our input would display some sort of indication when it was valid? Happily, there’s a :valid CSS selector for that. There’s also an :invalid selector. Enter your name in this demo:

You’ll notice the obvious caveat that invalid styles show up even before we’ve 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 the following demo, but browser support for :placeholder-shown is horrible and there isn’t a modern polyfill for it yet. Bummer.

For now, our best bet is to add some JavaScript to toggle a class depending on if the input is empty or not. Here’s the working demo:

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. We can then create a faux placeholder which beautifully slides out of the way as soon as the input is no longer empty. Here’s an example:

If the <span> being under the <input> offends your sensibilities or isn’t accessible enough, you can always tweak the JavaScript to add 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’s invalid.
  • Dim inputs as they’re filled out correctly.

Browser Support

  • Perfect in modern browsers and IE10+.
  • IE9- doesn’t support validation pseudo selectors so you won’t get the styling but the form still functions very nicely.

Possible Caveat

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!

Credit where it’s due

Danny King’s “Adaptive Placeholders” blog post got me thinking about this.