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 or add me on Google+.

web developer guide

my books

Book cover of Pro CSS3 AnimationPro CSS3 Animation, Apress, 2013

my projects

CSSslidy: an auto-generated #RWD image slider. 1.5K of JS, no JQuery. Drop in images, add a line of CSS. Done.

tipster.ioAutomatically provides local tipping customs and percentages for services anywhere.

Goodbye, JQuery Validation: HTML5 Form Errors With CSS3

css / forms

Estimated reading time: 3 minutes

CSS 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:

<input type="email" name="email" id="email">

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

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:

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> 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: let’s change the 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:

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

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

<input type="text" name="firstname" id="firstname" pattern="[^0-9][A-Za-z]{2,20}">
<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 this part of CSS3 won’t see the text, creating a state of graceful degradation.  We’ll make sure it’s the span element immediately after the input by using a sibling selector:

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:

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

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

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:

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

You can see the completed effect in the small form at the top of this article.

These techniques do not completely eliminate 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. JavaScript can also be used to customize the browser's own built-in validation error messages, as I show in the next article.

You’ll also need or some other server-side technology to act as a secure, impassable fallback for ultimate validation of user-submitted data. But the techniques demonstrated here continue to do what CSS should: push JavaScript into more advanced and useful areas, rather than being used for simple actions on a page.

comments powered by Disqus

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.