demosthenes.info

I’m Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with , and . To receive more information, including news, updates, and tips, you should follow me on Twitter.

featured articles

popular favourites

Goodbye, JQuery Validation: HTML5 Form Errors With CSS3

Working on the remake of this site’s user signup form, I very much wanted to keep to the design goals of simplicity, clarity, and ease of use I discussed in the previous article. Simultaneously, I wished to apply the same principles to my code. To me, this meant eliminating as much PHP and JavaScript as possible, and using CSS3 for most error messages and the appearance of invalid entry fields.

CSS3 allows for the detection of the status of HTML5 form elements through the use of the pseudo-class selectors :valid and :invalid. For the purposes of demonstration I’ll use the email input to start, as it has built-in validation:

  1. <input type=email name=email id=email size=30 maxlength=28>

Detecting whether the user has entered information correctly in the field is simple, using an attribute selector combined with the :valid pseudo-class:

  1. input[type=email]:valid { /* appearance for valid entry */ }

Changing the appearance of the input is good and fine, but I wanted to take the effect further, and add an error message if the information entered by the user was incorrect. One would think we could chain pseudo-class selectors together:

  1. input[type=email]:invalid:after { content: “Error message”; }

Sadly, we cannot use :after or :before directly on a form input. Like the <img> tag it is a replaced element: essentially, anything that would be closed inside of itself under XHTML, such as <img> or <hr>, cannot have generated content applied to it.

All is not yet lost: there is another way.

The technique that follows can be used on any input, including email, let’s change the input type attribute to text to keep things interesting. For this example, let’s say we are looking for a user’s first name. In that case, the regular expression we’ll use for pattern will be very simple: we won’t accept numerals, but anything else comprised of at least two upper or lowercase letters will be fine:

  1. <input type=text name=firstname id=firstname size=20 maxlength=18
  2. pattern="[^0-9][A-Za-z]{2,20}">

Let’s also add a span immediately after the input, with a title attribute that contains an error message associated with invalid content:

  1. <input type=text name=firstname id=firstname size=20 maxlength=18
  2. pattern="[^0-9][A-Za-z]{2,20}">
  3. <span title="Must be at least two letters, no numbers"></span>

We want to complete the span with the text of the title attribute. This will also mean that browsers that don’t support CSS3 won’t see the text, creating a state of graceful degradation.  We’ll make sure it’s the span after the input by using a sibling selector:

  1. input ~ span:after { content: attr(title); color: red; margin-left: 0.6rem; }

The default appearance of any generated content in the span will be invisible, via use of opacity:

  1. input ~ span:after { content: attr(title); color: red; margin-left: 0.6rem;
  2. opacity: 0; }

… but we’ll change that based on the invalidity of the information entered into the field immediately before it:

  1. input:invalid ~ span:after { opacity: 1; }

Done! But the appearance of the error message is a little sudden and clunky: it shows up just as soon as we type the first letter in the field, potentially distracting and confusing users. We’ll delay and fade in the message by using transition-property, duration and delay:

  1. input ~ span:after { content: attr(title); color: red; margin-left: 0.6rem;
  2. opacity: 0;
  3. -moz-transition-property: opacity;
  4. -moz-transition-duration: 2s;
  5. -moz-transition-delay: 2s;
  6. }

While you should add vendor prefixes to cover the other browsers, you will find that Webkit does not yet support transitions on :after or :before, so in Chrome and Safari the error messages will come up instantly. You can see the completed effect in the small form at the top of this article.

These techniques do not completely eliminate JQuery from forms: you’ll still need the scripting technology for features like AJAX validation (checking if a username is already registered in a database, for example), or to recreate the same effect in older browsers. You’ll also need or some other server-side technology to act as a secure inpassable fallback for ultimate validation of user-submitted data. But the techniques demonstated here continue to do what CSS3 should: push JavaScript into more advanced and useful areas, rather than being used for simple actions on a page.

You must be signed up in order to leave comments.

Great! works so well in Chrome, and trying to make it work in other browsers.

posted by Sumita Biswas

ok, cool enough. But on firefox that i'm using right now I still get the error that entered text is invalid while being numbers...So not so much cross browser? Plus, what about accessibility and semantics?

posted by motherfresh

Dudley StoreyThanks for your feedback, motherfresh. I've improved (and complicated) the regular expression used for validation - [^0-9][A-Za-z]{2,20} - which should take care of your issue in Firefox. Semantically, the input still makes sense, and JavaScript wouldn't make that any better... so accessibility in this solution should be the same for modern screen readers, unless you have information to the contrary.

posted by Dudley Storey

so we don't need the jQuery minimum length anymore:) cool!

posted by JoelB

And where's the catch? I was able to register with an invalid email address.

posted by Alecs Viper

Uh, that's not very nice. I was able to make two accounts with the same name and same password. Anyway, one thing I want you to pay attention: HTML code can be edited so HTML5 and Javascript validation must always be doubled by PHP validation. Cheers!

posted by Alecs Viper

Dudley StoreyAlecs, right now I don't have any kind of JavaScript backup to the HTML5 on the blog's sign-up form... so if you signed up with (say) IE8, the blog would allow you to go through, at least as it is currently written. And, as you point out, I haven't yet rolled out the version of the signup form that checks for duplicate names or eMail addresses. I've emphasized the fact that HTML5 doesn't check that an eMail address is "real" in my article on the eMail input... and as time allows, I'll improve the blog's user sign-up form. Thank you for your feedback!

posted by Dudley Storey

That's not what Alecs is saying. Why does HTML5 validation suck? Here's an example: This site lets you register the username "YourValidationSucks". The username input on this very page has a maxlength="16". So I can't login with a username that I have registered. So what do I do? Open up handy dandy Firebug, inspect the username input on this page, and delete maxlength="16". Now I can put in anything I want and click "login" and lo and behold, it accepts my 19 character username. But you, as the designer and developer of this site have specifically decided that you don't want to accept more than 16 characters in a username. Too bad. Without proper validation it's not you who makes decisions on what to accept here. It's your users, like me. So.....lesson is that CSS3 and HTML5 will NEVER be good enough to validate your website, as Mr. Storey has so kindly displayed here on his own site. I do hope you don't have MySQL limits on your database fields because someone trying to register illegal values on your sign up page can easily use this method and corrupt your tables.

posted by YourValidationSucks

Dudley StoreyThank you for your feedback, YVS - I've corrected the inconsistency between the signup and login form that you pointed out. However, your argument doesn't really stand: the same drawbacks you point out for HTML5 validation are true for every client-side process, including JavaScript, which can be altered just as easily. That's why I pointed out the requirement for some form of server-side process as a fallback, whichever form of validation you use... but your opinion has been noted, and I have given extra emphasis to this point in my latest revision of the article.

posted by Dudley Storey

web developer guide

featured comment

by Aisling Brock in New Business Card Design

what i'm reading

A Feast for Crows: A Song of Ice and Fire: Book Four
A Feast for Crows: A Song of Ice and Fire: Book Four

what i'm watching

Prometheus: Collector's Edition (Bilingual) [Blu-ray 3D + Blu-ray + DVD + Digital Copy]
Prometheus: Collector's Edition (Bilingual) [Blu-ray 3D + Blu-ray + DVD + Digital Copy]

what i'm playing

Borderlands
Borderlands

what i'm hearing

Planets
Planets

blogs

podcasts

no ads ever

This blog is free of advertising, and always will be.

creative commons licensed

The content of this blog is free to use in whatever way you wish under the Creative Commons license.