HTML5 Form Validation

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

A lot of the attention paid to HTML5 Forms has been centred around the new input types. email, url, date, and the rest are all very convenient, but for me the really useful feature is the built-in validation. In case you’re not aware of it, the browser will now handle all of the validation that we used to use JavaScript for.

This is great for the future, but although you can start using these functions now (in many browsers), they aren’t without their drawbacks – well, one big drawback really. I’m going to explain briefly the problem, and then propose a solution.

How Form Validation Works

The simplest form of validation is to say that a field is required, which is done by adding the required attribute (it’s boolean, so needs no explicit value):

<input type="text" required>

This will check to see if a value is supplied, and returns an error if it isn’t. You can add parameters to validation by using the pattern attribute with a JavaScript regex value; for example, to only accept a numeric value you would use the following:

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

Some field types have pattern validation baked in; email and url will only accept correctly formatted email addresses and URLs, respectively, while number and range can have maximum and minimum numeric values applied. There’s also a maxlength attribute to restrict the number of characters, which can also cause a validation error.

The Problem With Error Messages

Probably the biggest drawback of the validation process is that the error messages are, for the most part – and there’s no polite way to put this – ugly. Take a look at this image showing the validation error message in (from the top) Chrome, Opera, and Firefox:

Validation error messages in different browsers

I think the Opera message is the better of the three, but I think it’s fair to say that the designers weren’t having their best days when they made these. (I’m using Ubuntu here, but they really aren’t any better in any other OS.) The problem I have with these is that I’d like to use them, but I don’t think any designer I work with would find these acceptable and I’d no doubt end up using a JS implementation just to get some form of consistency.

Using JS is a short term solution, and there’s a good Validation API to aid in using it (which I aim to write about soon). But longer term we will need better-designed messages, or a way to style them ourselves, or both. I don’t think that the error messages need to look identical in every browser on every OS, but I do think they should be more closely aligned with the browser chrome and sympathetic to the OS; they should feel like a natural part of the platform, rather than an add-on.

A Proposal For Styling Error Messages

There’s no formalised suggestion for CSS styling of error messages, but I think it’s probably inevitable that there will be. This could take the form of a pseudo-element, perhaps something like:

input::error {}

This would allow us to set background, colour and font options. It may be necessary to also have a property to set where the validation error message appears in relation to the input it’s attached to; perhaps modifying position with values of above, below, before, or after:

input::error { position: below; }

And, perhaps, another property to set the appearance of the box which contains the message; perhaps the appearance property with values of box for a rectangle, or balloon for the current speech balloon style:

input::error { appearance: balloon; }

There’s also the text inside the validation error; the main message, and an optional extra which can be set with the title attribute (or JavaScript). These could have further pseudo-elements for finer control 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 plenty of development; but as there’s no formal proposal at the moment, it’s a good time to be thinking about these things.

16 comments on
“HTML5 Form Validation”

  1. Really good post Peter, and similar to the kinds of CSS-based error message solutions I’ve been thinking of. Can’t fault your logic in terms of how the new functionality would work WRT the rest of CSS.

    One thing you haven’t touched on is setting the actual error message text. I think a basic set of HTML attributes would work for this, something like

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

    When the required field is left empty, and

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

    ok, so this last example is not perfect, as you could just control this with min and max, but hey, you get the idea.

    You could even use HTML5 data attributes for this purpose, eg

    data-error-empty
    data-error-invalid

  2. I like your proposal for styling input::error { }, although would that not make it more difficult to style when you’re using a JavaScript fallback (when there’s no html5 form support)?

    I’m no expert, but I’m not sure you can select pseudo-elements (or create them) with js?

    Also, should we not just suggest styling ::error { } to cover errors from textareas etc.?

    Would be good to hear your thoughts Peter!

  3. @Chris: Thanks for the feedback. Firefox have implemented a custom attribute, x-moz-errormessage, which allows you to set a custom message, with extra detail being provided with the title attribute; for example:

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

    This would output the message Wrong! if the field was required but not completed, with the extra text Try again if the field was completed but the value was incorrect.

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

    @Russell: Using a pseudo-element selector shouldn’t affect styling in browsers which don’t support them – unless I’ve misunderstood your question. You can set pseudo-element styles in JS using insertRule() (or addRule() in IE). I think the ::error pseudo element would only apply to form elements which can be validated.

  4. I think the Firefox approach, as good as it sounds, may be very limiting. Think of inputs that have quite a few possible error states (a number that is required and has min and max, so need to handle empty field, underflow, overflow for instance)….are we going to have attributes for each of those errors as well?

  5. WebKit has already defined some pseudo-elements (of sorts) to allow control over the appearance of the validation bubble:
    http://trac.webkit.org/wiki/Styling%20Form%20Controls#WebKitr82179orolderChrome10and11

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

  7. Using form validation i found several blocking “features”.

    in wekbit :
    – type=number will only accept “.” as the decimal separator
    – type=date will only accept US date format

    And so Safari in iOS will choke without explanation, i took me a while to track the problem.

    For me the “blocking” point is the format limitation. I hope this will be “corrected” in the next versions as the implementation goes on.

    One can use the form validation API, but for the type / format / pattern mix there are several inconsistencies.

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

  8. Why not use the content property that already exists, no need for ::error-message. So it would look something like

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

  9. Excellent post. Hopefully we’ll see good progress in the near future.

    Regarding what @Gerben and @Patrick said, I believe the markup (attributes in the form elements) is the right place to specify custom error messages -unless, of course, you prefer to use the browsers’ default messages.

  10. […] have also been suggestions mentioned by Peter Gasston on how we could add some new CSS pseudo-classes to handle this. For […]

  11. Hello, validation in html5 is very good with required attribute, but it accept the white space,

    is any solution for rejecting the white spaces ?

    thank you

  12. I agree with the comment left by kunal. No real-life web form will allow Submit if a required field contains spaces only. The ‘required’ attribute in its current form is for all intents and purposes useless.

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

  13. […] ::-webkit-validation-bubble-message. There’s no cross-browser proposal at W3C, but Peter Gasston has interesting ideas. The only reliable way at the moment to control the appearance of validation is turn it off with […]

  14. […] the book was published, Bruce has written a little more on the styling of forms and there is another post from Peter that is useful […]

  15. nice!!!, it is really helpful your blog. I hate Mozilla, grrr they should use some standard to write the invalid message. Is error-empty compatible with Safari, Opera ? Of course I have to use x-moz-errormessage for Mozilla

  16. […] the book was published, Bruce has written a little more on the styling of forms and there is another post from Peter that is useful […]