HTML5 Form Validation

Warning This article was written over six months ago, and may contain outdated information.

A lot of the atten­tion paid to HTML5 Forms has been cen­tred around the new input types. email, url, date, and the rest are all very con­ve­nient, but for me the real­ly use­ful fea­ture is the built-in val­i­da­tion. In case you’re not aware of it, the brows­er will now han­dle all of the val­i­da­tion that we used to use JavaScript for.

This is great for the future, but although you can start using these func­tions now (in many browsers), they aren’t with­out their draw­backs — well, one big draw­back real­ly. I’m going to explain briefly the prob­lem, and then pro­pose a solution.

How Form Validation Works

The sim­plest form of val­i­da­tion is to say that a field is required, which is done by adding the required attribute (it’s boolean, so needs no explic­it value):

<input type="text" required>

This will check to see if a val­ue is sup­plied, and returns an error if it isn’t. You can add para­me­ters to val­i­da­tion by using the pattern attribute with a JavaScript regex val­ue; for exam­ple, to only accept a numer­ic val­ue you would use the following:

<input type="text" pattern="[-0-9]+" required>

Some field types have pat­tern val­i­da­tion baked in; email and url will only accept cor­rect­ly for­mat­ted email address­es and URLs, respec­tive­ly, while number and range can have max­i­mum and min­i­mum numer­ic val­ues applied. There’s also a maxlength attribute to restrict the num­ber of char­ac­ters, which can also cause a val­i­da­tion error.

The Problem With Error Messages

Prob­a­bly the biggest draw­back of the val­i­da­tion process is that the error mes­sages are, for the most part — and there’s no polite way to put this — ugly. Take a look at this image show­ing the val­i­da­tion error mes­sage in (from the top) Chrome, Opera, and Firefox:

Validation error messages in different browsers

I think the Opera mes­sage is the bet­ter of the three, but I think it’s fair to say that the design­ers weren’t hav­ing their best days when they made these. (I’m using Ubun­tu here, but they real­ly aren’t any bet­ter in any oth­er OS.) The prob­lem I have with these is that I’d like to use them, but I don’t think any design­er I work with would find these accept­able and I’d no doubt end up using a JS imple­men­ta­tion just to get some form of consistency.

Using JS is a short term solu­tion, and there’s a good Val­i­da­tion API to aid in using it (which I aim to write about soon). But longer term we will need bet­ter-designed mes­sages, or a way to style them our­selves, or both. I don’t think that the error mes­sages need to look iden­ti­cal in every brows­er on every OS, but I do think they should be more close­ly aligned with the brows­er chrome and sym­pa­thet­ic to the OS; they should feel like a nat­ur­al part of the plat­form, rather than an add-on.

A Proposal For Styling Error Messages

There’s no for­malised sug­ges­tion for CSS styling of error mes­sages, but I think it’s prob­a­bly inevitable that there will be. This could take the form of a pseu­do-ele­ment, per­haps some­thing like:

input::error {}

This would allow us to set back­ground, colour and font options. It may be nec­es­sary to also have a prop­er­ty to set where the val­i­da­tion error mes­sage appears in rela­tion to the input it’s attached to; per­haps mod­i­fy­ing position with val­ues of above, below, before, or after:

input::error { position: below; }

And, per­haps, anoth­er prop­er­ty to set the appear­ance of the box which con­tains the mes­sage; per­haps the appearance prop­er­ty with val­ues of box for a rec­tan­gle, or bal­loon for the cur­rent speech bal­loon style:

input::error { appearance: balloon; }

There’s also the text inside the val­i­da­tion error; the main mes­sage, and an option­al extra which can be set with the title attribute (or JavaScript). These could have fur­ther pseu­do-ele­ments for fin­er con­trol over the text formatting:

input::error-message { }
input::error-text { }

This is all straight off the top of my head, of course, and no doubt needs plen­ty of devel­op­ment; but as there’s no for­mal pro­pos­al at the moment, it’s a good time to be think­ing about these things.

16 comments on
“HTML5 Form Validation”

  1. Real­ly good post Peter, and sim­i­lar to the kinds of CSS-based error mes­sage solu­tions I’ve been think­ing of. Can’t fault your log­ic in terms of how the new func­tion­al­i­ty would work WRT the rest of CSS.

    One thing you haven’t touched on is set­ting the actu­al error mes­sage text. I think a basic set of HTML attrib­ut­es would work for this, some­thing like 

    <input type="date" error-empty="please enter the date you want to attend the performance on">

    When the required field is left emp­ty, and

    <input type="date" error-invalid="please enter a date between March 30 and April 31">

    ok, so this last exam­ple is not per­fect, as you could just con­trol this with min and max, but hey, you get the idea. 

    You could even use HTML5 data attrib­ut­es for this pur­pose, eg


  2. I like your pro­pos­al for styling input::error { }, although would that not make it more dif­fi­cult to style when you’re using a JavaScript fall­back (when there’s no html5 form support)?

    I’m no expert, but I’m not sure you can select pseu­do-ele­ments (or cre­ate them) with js?

    Also, should we not just sug­gest styling ::error { } to cov­er errors from textar­eas etc.?

    Would be good to hear your thoughts Peter!

  3. @Chris: Thanks for the feed­back. Fire­fox have imple­ment­ed a cus­tom attribute, x-moz-errormessage, which allows you to set a cus­tom mes­sage, with extra detail being pro­vid­ed with the title attribute; for example:

    <input type="text" x-moz-errormessage="Wrong!" title="Try again">

    This would out­put the mes­sage Wrong! if the field was required but not com­plet­ed, with the extra text Try again if the field was com­plet­ed but the val­ue was incorrect.

    Not sure if this is the best approach, but it works.

    @Russell: Using a pseu­do-ele­ment selec­tor should­n’t affect styling in browsers which don’t sup­port them — unless I’ve mis­un­der­stood your ques­tion. You can set pseu­do-ele­ment styles in JS using insertRule() (or addRule() in IE). I think the ::error pseu­do ele­ment would only apply to form ele­ments which can be validated.

  4. I think the Fire­fox approach, as good as it sounds, may be very lim­it­ing. Think of inputs that have quite a few pos­si­ble error states (a num­ber that is required and has min and max, so need to han­dle emp­ty field, under­flow, over­flow for instance).…are we going to have attrib­ut­es for each of those errors as well?

  5. WebKit has already defined some pseu­do-ele­ments (of sorts) to allow con­trol over the appear­ance of the val­i­da­tion bubble:

  6. @Nicolas: Yes, I’d already seen them and that’s going to be the sub­ject of my next post!

  7. Using form val­i­da­tion i found sev­er­al block­ing “fea­tures”.

    in wek­bit :
    — type=number will only accept “.” as the dec­i­mal separator
    — type=date will only accept US date format

    And so Safari in iOS will choke with­out expla­na­tion, i took me a while to track the problem.

    For me the “block­ing” point is the for­mat lim­i­ta­tion. I hope this will be “cor­rect­ed” in the next ver­sions as the imple­men­ta­tion goes on.

    One can use the form val­i­da­tion API, but for the type / for­mat / pat­tern mix there are sev­er­al inconsistencies.

    gmoulin_dev [June 15th, 2011, 16:07]

  8. Why not use the con­tent prop­er­ty that already exists, no need for ::error-mes­sage. So it would look some­thing like

    input::error {
    content: "Wrong value!"; /* or */
    content: attr(data-errormessage);
    color: white;
    background: red;
    border: solid 2px blue;
    position: below;

  9. Excel­lent post. Hope­ful­ly we’ll see good progress in the near future.

    Regard­ing what @Gerben and @Patrick said, I believe the markup (attrib­ut­es in the form ele­ments) is the right place to spec­i­fy cus­tom error mes­sages ‑unless, of course, you pre­fer to use the browsers’ default messages.

  10. […] have also been sug­ges­tions men­tioned by Peter Gasston on how we could add some new CSS pseu­do-class­es to han­dle this. For […]

  11. Hel­lo, val­i­da­tion in html5 is very good with required attribute, but it accept the white space, 

    is any solu­tion for reject­ing the white spaces ?

    thank you

  12. I agree with the com­ment left by kunal. No real-life web form will allow Sub­mit if a required field con­tains spaces only. The ‘required’ attribute in its cur­rent form is for all intents and pur­pos­es useless.

    Jan Hrabowski [October 27th, 2012, 07:10]

  13. […] ::-webkit-val­i­da­tion-bub­ble-mes­sage. There’s no cross-brows­er pro­pos­al at W3C, but Peter Gasston has inter­est­ing ideas. The only reli­able way at the moment to con­trol the appear­ance of val­i­da­tion is turn it off with […]

  14. […] the book was pub­lished, Bruce has writ­ten a lit­tle more on the styling of forms and there is anoth­er post from Peter that is useful […]

  15. nice!!!, it is real­ly help­ful your blog. I hate Mozil­la, grrr they should use some stan­dard to write the invalid mes­sage. Is error-emp­ty com­pat­i­ble with Safari, Opera ? Of course I have to use x‑moz-errormes­sage for Mozilla

  16. […] the book was pub­lished, Bruce has writ­ten a lit­tle more on the styling of forms and there is anoth­er post from Peter that is useful […]