Avoid Default Field Validation

HTML5 gives us form field validation for free. The problem is that the default messages browsers provide are not always useful and typically do not work with assistive technology.

I made an example on CodePen that uses an email field (type="email"), is required (required), and uses a pattern to restrict the email address to the domain foo.com (pattern=".+@foo.com").

<form action="#" method="get">
    <label for="email">Email</label><br>
    <input type="email" id="email" required pattern=".+@foo.com">
    <input type="submit">

See the Pen Untitled by Adrian Roselli (@aardrian) on CodePen.

I then fired up three Windows screen readers across four browsers and recorded the output. Note how in each case the browser announces the field as invalid as soon as it gets focus. It also does not identify what the pattern is for the field, nor when the field has become valid (meaning we got the format right).

Firefox 65 and NVDA 2018.3.2.
Internet Explorer 11 and JAWS 2018.
Chrome 71 and JAWS 2018.
Edge and Narrator on Windows 10 as February 2019.

Using required on its own will not identify to all users in plain text that a field is required. You will still need to indicate it in the text label otherwise you could fail 3.3.1 Error Identification (A).

If you use a pattern, you cannot rely on the browser to show the user what the pattern is. If you do not explain it as part of the accessible name, you can fail 3.3.2 Labels or Instructions (A) and 3.3.3 Error Suggestion (AA).

The default browser error indicator, when one is shown, tends to be a red outline. With a default contrast ratio of 4.0:1 on a white background, it would not fail 1.4.11 Non-text Contrast (AA) as noted in John’s comment below, but that is still not very good. Relying only on the outline would also fail 4.1.2 Name, Role, Value (A).

I am making some broad statements here. But by the time you amend the default error handling, replace the text, create better styles, and ensure states are conveyed to assistive technology, you might as well skip the built-in and write your own.

Don’t take my dismissive tone to mean that writing your own is easy. It takes some rigor, as this post on required and aria-required demonstrates. But it is part of the job.

Update: 4 May 2022

Three years on and this post is still accurate. The disappearing error messages in Chromium are one ongoing challenge, and browsers still do not respect zoom.

In Chrome 100, the error message stays visible for 5 seconds, with seemingly no way to extend it. In Firefox and Safari, the message persists (which is what you want).
In Firefox 99 I can zoom the page and while the content scales (only to 170% in this video) the error message does not. Compare the message at 0:01 and 0:09. This also occurs in Chromium and WebKit browsers.
Here, Edge wants so much to help me get the right email address (redacted) and password into the login form that it hides the error message. Which disappears just after I clear the field hints owing to the 5 second time-out. This makes Safari’s decision to display the message above the field seem better and honors my rule against displaying error messages under fields.

For the zoom issue, Cezary Tomczyk filed an issue against Chromium and I filed an issue against Firefox and WebKit (with videos):

I also filed an issue against Chromium for the message timeout:

Update: 5 May 2022

To tweak the above a bit, Chromium browsers on Windows will scale the default error message, but not while it is displaying. The message has to be redrawn to honor the page zoom. Since they self-dismiss, I guess this forces you to regenerate the error to see it at the preferred size?

In Chrome 100, the error message does not scale as I zoom the page (0:01–0:04). Until the message disappears on its own and I make it reappear (0:08). Then it has scaled.

Update: 10 August 2023

Progressively Enhanced Form Validation, Part 1: HTML and CSS at the Cloud Four blog goes beyond what I talk about here and looks at CSS pseudo classes for form elements and their actual support.



Hi Adrian,

I (and friends) tried to see how this default behaviour can be altered. It’s still being discussed: https://github.com/whatwg/html/issues/4818

In response to Stéphane. Reply

Awesome. I appreciate you pushing it.


Isn’t the error outline contrast requirement 3:1? At 4:1 this would pass 1.4.11 Non-text Contrast (AA). You’re spot on in that the outline alone would be insufficient.

John Lukosky; . Permalink
In response to John Lukosky. Reply

Oops. Yeah. I am so used to always running at this with a 4.5:1 minimum that I got carried away. Will fix.

Leave a Comment or Response

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>