HTML5 Form Validation Fallback (without a library)

Currently HTML5 form validation doesn’t work in every modern browser. Chrome, Firefox, and IE all have beautiful error reporting, but we can’t say the same about Safari or iOS. Mac’s webkit based browsers display no error messages, nor do they prevent submissions when the form is invalid (see screenshot). The oddest part is Safari actually supports HTML5 form validation almost completely. In order to get things working we’ll teach you how to write an HTML5 form validation fallback that relies on CSS and a snippet of JavaScript.

Current state of HTML5 form validation out of the box. Everything works except Safari’s Webkit based browsers. Which is a huge deal since it leaves out iPhones and iPads. To view a demo of the fallback you’ll create click here

For this article we’ll be covering how to write an HTML5 form validation fallback from the ground up without any library. You’ll learn how to create custom error output and a polyfill for supporting browsers. Here is a list benefits on why this is the best solution.

  • Roughly 20 lines of code
  • Easily customizable via CSS
  • Only fixes browsers that don’t display HTML5 error messages
  • Focused on modern browsers without legacy browser support bloat
  • Can be implemented easily without any library (although we used jQuery to speed things along)

View CodePen Demo

Please note that CodePen’s use of iframes may cause issues with validation messages. If you’re having issues download the validation form example and run locally.

Fixing broken HTML5 Form Validation

For gracefully degradation with browsers that don’t support HTML5 form validation, we’re using CSS. But first we need some HTML.

Valid HTML5 Markup

Below you’ll find a required tag, validation pattern, and title attribute for validation. These and any other supported validation tags will work fine with our fallback.

<form class="validate-form">
  <input type="text"
         title="required input" <!-- Titles are used for custom error messages -->
         required /> <!-- Required forces this input to be filled in -->
  <input type="text"
         title="Must be 5 numeric numbers"
         placeholder="zip code"
         pattern="\d{5}" <!-- Patterns will accept any RegEx you can dream up, just be sure to include a title for error output -->
         maxlength="5" <!-- Maximum allowed length on input -->
         required />
  <input type="submit" />

Your markup will look something like this. Expect slight variations in different browsers.


Add error detection with CSS

Our CSS fix requires us make use of the :required:invalid pseudo class selector. Problem with this selector is it automatically marks your form inputs as invalid. Reason being inputs are validated on page load. To prevent false positives error messages you’ll need to add a class of .invalid, which we’ll apply after the user has submitted a form.

/* .invalid class prevents CSS from automatically applying */
.invalid input:required:invalid {
  background: #BE4C54;

/* Mark valid inputs during .invalid state */
.invalid input:required:valid {
  background: #17D654 ;

For validation in browsers where HTML5 forms are available

In order to detect if HTML5 form validation is available, you’ll need to check a <form> tag for the checkValidity() method. Calling checkValidity() is how a modern browser checks to see if a form is valid based upon your markup. Pop this snippet into your code to check for support.

function hasHtml5Validation () {
 return typeof document.createElement('input').checkValidity === 'function';

Webkit browsers support this method, but they don’t call it when a user hits submit. On form submission force fire checkValidity(). If its available your form will magically work after applying a .invalid class. Its that simple! We used a few lines of jQuery in our example, but they can easily be replaced with vanilla JavaScript.

if (hasHtml5Validation()) {
 $('.validate-form').submit(function (e) {
   if (!this.checkValidity()) {
     // Prevent default stops form from firing
   } else {

html5 form validation fallback demo
Here is a working example of your HTML5 form validation fallback in Safari.

View Gist on GitHub

Concerning Title Messages

Our demo example doesn’t use title messages, but they can be supported. Just check inputs on submission to see if they’re invalid and have a title. A quick logic flow of what this might look like:

  1. On submission hide all title messages
  2. Check each input with a title
  3. If the input is invalid inject/display your error title attribute message

Further Validation Resources

To create the above solution I found these articles helpful.

17 thoughts on “HTML5 Form Validation Fallback (without a library)”

  1. This is still a really nice workaround, even though it’s now 3 years old. I am baffled that Safari still can’t do this itself!

    The code above doesn’t actually show the error messages, it just shows the word “invalid”. For anyone wanting to actually show the title attribute as the error message instead:

    In the Javascript, change this line:


    To this:

    $(‘#status’).html($(“.invalid input:required:invalid”).attr(‘title’));

  2. Great Solution!
    I was having problems to validate forms on Iphones. This worked!

    I just want to add a recommendation, if you are using AngularJS put the javascript code given here inside the controller.

  3. I see you share interesting things here, you can earn some additional cash, your blog
    has big potential, for the monetizing method, just search in google –
    K2 advices how to monetize a website

  4. Thanks Ash.

    Quick and elegant solution. This was a lifesaver after we converted some sites to HTML5 validation.



      1. I read a lot of interesting posts here. Probably you spend a lot of time writing, i know how to save you a lot of time, there is an online tool that creates unique, google
        friendly articles in minutes, just type in google – laranitas free content source

  5. It works beautifully for text boxes. Thank you. I’m guessing I need additional code/css for check boxes. It doesn’t seem to respond for a check box.

    1. Not too sure how much validation is supported on text boxes or radio buttons at the moment. One way to get around it might be adding some :before { content: ‘my content’ } on invalid for a checkbox (if you’re having problems). What are you trying to validate on a text box and what browser?

    1. Thanks Micheal, focus of the article is to help fix (what I consider) the currently broken HTML5 form implementation in iOS. Good link though to a more thorough overview of HTML5 forms.

Leave a Reply

Your email address will not be published. Required fields are marked *