Playing with the Constraint Validation API
I'm a huge advocate of using the native features of HTML5. A lot of people don't know what this language is really capable of. Amongs all of these features, there are a lot of built-in API like the Constraint Validation API.
⚠️ This post will be talking about client-side validation. It should never replace server-side validation as it's mostly used to improve the user experience.
HTML5 validation API
People are probably familiar with the default tooltip messages that may appear when filling form fields. This is what we're talking about. If we go deeper in details, this API offers some nice methods and properties to play with validation states of inputs and forms.
Getting the validation state
This native API first allows us to get information about the validation state of form fields: the
checkValidity() method can be called on form elements (
<fieldset>). It returns a boolean (
true is the field is valid,
const field = document.querySelector('input') const isFieldValid = field.checkValidity() // 'true' or 'false' console.log(isFieldValid)
This method fires an
invalid event (which is also fired when the form is submitted). This event can then be used to perform some actions like displaying an errors summary:
Setting a custom validation message
By default, the browser handles fields with errors by displaying a tooltip with an error message according to the field validation constraints (required or not, format, length...). These error messages are fully customizable with the
setCustomValidity() method. Messages can then be retrieved with the
validationMessage input property.
const field = document.querySelector('input') field.setCustomValidity('The value must contain at least one number.') // 'The value must contain at least one number.' console.log(field.validationMessage)
A real form example
I made a real world example of a form using the Constraint Validation API. TL;DR: see the demo and the code.
The HTML code is pretty straightforward:
- I created a payment form with 3 fields: "card number", "expiration date" and "security code".
- Each field is validated against 3 rules: format, length and requirement (
requiredattributes). It also has an associated label and error message slot.
- The fields are wrapped inside a
<form>container which has a submit button at its end.
<textarea>) as a parameter. Depending on the element state (empty, valid or invalid), it:
- Defines a custom validation message (with
- Fills the error slot with the message.
- Sets an
aria-describedbyattribute to link the error and the field.
To insure a proper user experience, the validation is triggered once the user clicks the submit button or on every field's
change event. As the native validation tooltip is only showing up on form submission, it is safe to also trigger validation on
submit event can not be used here because it is only called when all fields are valid.
Can we safely rely on this?
The browser support is really good: all modern browsers and Internet Explorer supports the Constraint Validation API (see on Can I Use).
The experience is optimized (error messages set with
setCustomValidity() are correctly announced when focusing a field) on some screen readers / browsers combinations. Here is my tests suite:
- VoiceOver + Safari: ✅
- VoiceOver + Chrome: ✅
- VoiceOver + Firefox: ❌
- NVDA + Firefox: ✅
- NVDA + Chrome: ✅
- Talkback: ✅
As a security net, I added a visually hidden error message near each input which is filled when the field is invalid. The field's input is then properly described with the error message (
So my answer is: yes, it is safe to use it. Thanks for reading!