Accessible Form Validation with ARIA and Vue.js

Accessible Form Validation with ARIA and Vue.js

Accessible Form Validation with ARIA and Vue.js. Did you know that in your client-side validation errors in your web forms, and even additional instructions you provide for your form fields, might not be heard by screenreader users?

In this article you'll learn how to use ARIA and Vue.js to make your form error messages and instructions more accessible to all of your users.

How Screen Readers Navigate and Read Forms

Any developer who is building forms with accessibility in mind needs to understand some important differences between how a sighted user and a screen reader user "reads" web forms. The first is that there is a "hidden" dimension of your web page known as the "accessibility tree". The accessibility tree is a DOM-like structure that enable the screenreader get information from your browser.

Using ARIA, the developer can customize certain aspects of the page to enhance the accessibility of your content and overall experience for screenreader users.
A second difference is that the two most popular screenreaders use (or can use) a specific mode known as "forms" or "focus" mode to navigate web forms more easily. While in forms mode, the screenreader enables the user to navigate among the form's interactive controls with the keyboard. When the focus arrives at a control, the screenreader reads both the input and and the associated label. That's pretty slick, isn't it?

What About Error Messages and Instructions?

Forms mode sounds pretty useful — but what about the other items that we often add to forms, such as validation error messages, or instructions we might want to provide for fields (hints for required formats, acceptable or required characters, etc.). If the developer places these within an element that is not inherently focusable, such as a <div> or <p>, a screenreader in forms mode will skip right over them. That's not what we want! So how do we ensure that screenreader will read this additional (and ofen essential) information?

Method 1: What's in a name?

By far the easiest way to make your validation error messages accessible is to make them a child of the <label>element. By making the error message part of the label, the message becomes part of the accessible name for the control — in this case, the input element – and will be read when ever the control has focus. Of course, you will want to use Vue’s v-show directive to hide the error message until there is a validation error. Since it utilizes CSS’s display: none, v-show will also keep the error message out of the accessibility tree, which hides it from screen readers.

For some, this can be a quick and easy solution. It doesn’t require any ARIA, keeps your code simple, and minimizes the possibilities for coding errors.

Method 2: Use aria-describedby

But what if you would rather not have your error messages within the <label> element? There might be good reasons for this. For example, tampering with the control’s accessible name when there is an error might seem like a kludge. Or perhaps you want to place the messages someplace else relative to the control, or even display them within their own list or block element (both of which are invalid inside <label>).

If you prefer to keep accessible name "pure", or want more flexibility, you can still make your error messages accessible. ARIA ("Accessible Rich Internet Applications") attributes enable developers to add semantics where HTML alone isn't sufficient. ARIA attributes have no effect on a sighted user's web experience. But they do affect how screen readers interpret a page through the accessibility tree.

As luck would have it, ARIA provides an attribute that enables developers to associate other html elements with a form field: aria-describedby. To provide field instructions, simply add the aria-describedby attribute to the field input with the id of each element you want to link with the input. The ids should be space-separated and entered in the order you want them read.

<label for="first_name">First Name:</label>

<input id="first_name" type="text" aria-describedby="first_name-instructions">

<div id="first_name-instructions">maximum length 30 characters</div>

Wen the focus is placed on the <input>, the screenreader will say something like this:

"First name colon edit. maximum length 30 characters edit"

Now that we have explicitly associated additional instructions with our field, we also want to add an error messages. Let's try this:

<div id="first_name-error">
Please enter a valid project name.

<label for="first_name">First Name:</label>

<div id="first_name-instructions">maximum length 30 characters</div>

<input id="first_name" name="first_name" type="text" aria-describedby="first_name-instructions first_name-error">

And with one simple attribute, we have added an error message and associated it with the form input.

Vue.js Makes It Easy

But we're not done yet. First, we don't want the error message to be displayed and read all of the time; we only want to see or hear it when there is an error. This example uses the excellent Vuelidate library.

<div id="first_name-error" v-show="first_name.$error">
Please enter a valid project name.

<label for="first_name">First Name:</label>

<div id="first_name-instructions">maximum length 30 characters</div>

<input id="first_name" name="first_name" type="text" v-model="$v.first_name.$model" :aria-invalid="$v.first_name.$invalid" aria-describedby="first_name-instructions first_name-error">

Now we have an error message that is associated with the field input, but will be visually hidden unless a validation error is detected. Since we are using v-show, we might expect the message to be hidden from screen readers as well, and under most circumstances, it will. But here we encounter a feature of aria-describedby that might seem counter-intuititive: by default, it will read a referenced element even when that element is hidden. (it makes no difference whether this is done by css or aria-hidden). To make our solution work as intended, we need to make aria-describedby dynamic so that it adds the id for the error message only when therre is an error. Of course Vue.js makes this quite easy. Have a look at this example:


<div id="first_name-error" v-show="first_name.$error">
Please enter a valid first name

<label for="first_name">First Name:</label>

<div id="first_name-instructions">maximum length 30 characters</div>

<input id="first_name" name="first_name" type="text" v-model="$v.first_name.$model" :aria-invalid="$v.first_name.$invalid"  :aria-describedby="describedBy('first_name')">


methods: {

    // generate aria-describedby reference ids 	

    describedBy(field) {

        const inst = `${field}-instructions`

        // field.$error is a boolean computed property returned by Vuelidate
        // if there is an error, valErr becomes the field id. Otherwise it is an empty string.

        const valErr = field.$error
        ? `${field}-error`
        : ''

        //trim and replace double-spaces with single space
        let refString =  ` $ {valErr} ${inst}`.replace(/\s+/g,' ').trim()

        return refString


    // a basic error message builder      	

    vMessage(v, field) {

        let message = ''

        let errors = []

        if ($v.$error)) {

            // get error types from Vuelidate $params
            let errorTypeKeys = Object.keys($v["$params"])

            // build errors array

            for (const key of errorTypeKeys) {
                if ($v[key] === false) {

            //build comma=separated string from array

            let errorString = errors.length > 1
            ? errors.join(', ')
            : errors[0]

            // convert to more readable message

            errorString = errorString
                .replace('required', 'This is a required field')
                .replace('url', 'The url is invalid')
                .replace('email', 'The email address is invalid')
                .replace('minLength', 'Input does not meet minimum length')

            message = `${errorString}.`

        return messsage



Now we have a dynamic aria-describedby attribute that is bound to the output of the describedBy()method. describedBy() takes the field name as a parameter; determines whether the field input is valid; and returns the appropriate string of space-separated list of ids. If there is an error, and the focus is placed on the <input>, aria-describedby will reference both the error message and the instructions, and the screen reader will announce both. Otherwise, the screen reader will announce only the instructions (the <label> will be announced regardless).

Some caveats

Developers should be aware that, as with web browsers, screen readers are not all the same. They can interpret html or ARIA in their own unique way, have their own feature sets, and their functionality can vary when used with different web browsers. For example, both JAWS and NVDA support both forms (focus) mode and aria-describedby, while Voiceover supports aria-describedby, but it does not have a focus or forms mode. NVDA seems to work most reliably with Firefox, while Voiceover seems to work best with Safari.

While there is broad support for aria-describedby among screen readers and (modern) web browsers, it does have some behaviors that developers should be aware of. For example, in addition to reading hidden referenced elements (above), aria-describedby seems to disregard semantics; it reads referenced elements as a continuous string. If your instructions and messages contain lists or other nested elements, the semantics will be ignored, and in some cases, the content might not be read at all. Therefore, it is best to keep message content short and simple, and use punctuation. For a complete list of caveats, see the Scott O'Hara article cited at the end of this article.

The future: aria-errormessage

Using aria-describedby for validation error messages might not seem like an especially elegant solution. Of course, ARIA is still relatively young. In late-2017, ARIA 1.1 added the aria-errormessage attribute, which is intended to deal specifically with validation error messages. When it gains support in screen readers and browsers, aria-errormessage will be used together with the aria-invalid attribute to provide a more coherent method for reading out the error message. But as of this writing, support for aria-errormessage is still poor to nonexistent, so for now, developers should user aria-describedby to make form field instructions and errors more accessible.


All of the above should make it clear that neither automated tools nor visually viewing the site yourself can tell you whether your forms are working as intended, and are providing an inclusive experience for all users. The only way to ensure this is by testing with a screen reader. So fire up a copy of NVDA, Voiceover (both free), or JAWS (if you can afford it), get under “the hood” and start exploring the non-visual dimension of the web. You may be surprised by what you hear — and discover.

Recommended Reading

How to use PWA plugin in Vue CLI 3.0

How to Using Cypress with Django and Vue for integration testing in GitLab CI

Going Serverless with Vue.js

What React Hooks Mean for Vue developers

Build a Single-Page App with Go and Vue

Server Side Pagination with Vue.js and Node

Build Your First PWA with Vue and TypeScript

What are the differences between the various JavaScript frameworks? E.g. Vue.js, Angular.js, React.js

What are the differences? Do they each have specific use contexts?

What are the differences? Do they each have specific use contexts?

Ember.js vs Vue.js - Which is JavaScript Framework Works Better for You

Ember.js vs Vue.js - Which is JavaScript Framework Works Better for You

In this article we will discuss full details and comparison of both Ember.js and Vue.js

JavaScript was initially created to work for web applications. But today they have become the favorite of mobile app developers. Most of the developers prefer to work with frameworks based on JavaScript. It simplifies coding. You can use JavaScript with almost any framework.

The use of a particular framework will decide how easy and fast it is to create the app. So, you must choose the best one suited for the app that you are planning to build. You must make a wise choice so that you benefit in the end. Among the crowded market, two of the frameworks stand out. We will make a comparison between Ember.js and Vue.js.

Why Do You Select A Particular Framework?

Before we start comparing the two frameworks, we should understand the factors that lead to the choice of a framework. Each developer chooses a framework before he or she goes to work on an app. Let us see the reasons for the selection.

● The codes must be easy to understand and transparent.

● The framework should give the maximum power with the least amount of coding.

● The framework should provide a well laid out structure to work on.

● Does the framework support an in-built router or an external plug-in router?

● The framework should be able to transfer more data on a full page-load so that it becomes a single-page app. A single-page app is more beneficial for the application.

● In single page architectures if there is a need for users to share links to sub-screens within the interface, then the framework should have the capacity to route based on the URL.

● A tighter template option can help in enabling two-way binding.

● The framework should not conflict any third-party library.

● Testing the codes inside the framework should be easy.

● The framework should provide the HTTP client service for AJAX calls

● The documentation is essential. It should be complete and up-to-date.

● The framework should be compatible with the latest version of the browser.

● The framework has to fulfill the above conditions for easy construction of the app. You must ensure that the framework you choose meets the conditions.

Vue.js Explained

Developers are always looking at new frameworks to build their apps. The main requirements are speed and low cost. The framework should be easy to use by even new developers. You should be able to use it at low cost. Other considerations are about simple coding, proper documentation, etc.

Vue.js combines a lot of good when it comes to software language for web app development. The architecture of Vue.js is easy to put in use. The apps developed using Vue.js are easy to integrate with new apps.

Vue.js is a very lightweight framework. It makes it fast to download. It is also much faster than other frameworks. The single-file component nature of the framework is also beneficial. The size has made it very popular.

You can further decrease weight. With Vue.js you can separate the template-to-virtual DOM and compiler. You can only deploy the minified and zipped interpreter which is only 12 KB. You can compile the templates in your machine.

Another significant advantage of Vue.js is that it can integrate easily with existing applications created with JavaScript. It will make it easy for using this framework to make changes to applications already present.

Vue.js also integrates easily with other front-end libraries. You can plug in another library and make up for any deficiency in this framework. This feature makes this tool a versatile one.

Vue.js uses the method of rendering on the streaming-side server. You can render your component and get a readable stream. You can then send this to the HTTP server. It makes the server highly responsive. Your users will get the rendered content very quickly.

Vue.js is very SEO friendly. As the framework supports server-side rendering, the views are rendered directly on the server. The search engines list these.

But the most important thing for you is the ease with which you can learn Vue.js. The structure is elementary. Even new developers will find it easy to use it to build their apps. This framework helps in developing both small and large templates. It helps to save a lot of time.

You can go back and check your errors very easily. You can travel back and inspect all the states apart from testing your components. It is another important feature as far as any developer is concerned.

Vue.js also has very detailed documentation. It helps in writing your applications very quickly. You can build a web page or app with the basic knowledge of HTML or JavaScript.

● Vue.js has pure architecture. It helps in integration with other apps

● Vue.js is lightweight and fast. It can be made lighter by deploying only the interpreter

● You can separate the compiler and the template-to-virtual DOM.

● Due to smooth integration, you can use this to make changes to existing apps

● To make up for any shortfall, you can plug-in any library and makeup.

● As Vue.js uses streaming-side server rendering, your users can get quick responses.

● The server-side rendering also helps in being ranked higher by search engines.

● It has a simple structure. Easy to use for any new developer

● You can go back and check and correct your errors.

● You can check all the existing states.

● Detail documentation also helps build the web page or application very quickly.

Ember.js Decoded

Ember.js is an MVVM model framework. It is open-source software. This platform is mostly used for creating complex multi-page applications. It maintains up-to-date features without discarding any of the old features.

With this framework, you have to follow the architecture of the framework strictly. The JS framework is very tightly organized. It reduces the flexibility that other frameworks might offer.

There is a very refined and developed control system for its platforms and tools. You can integrate it with the new version with the tools provided. There is strict guidance about avoiding outdated APIs.

You can understand Ember’s APIs easily. They are also easy to work. You can make use of highly complex functionalities simply and straightforwardly.

The performance is better as similar jobs are processed together. It creates batches of similar bindings and DOM updates to improve the performance. It means that the browser needs to process them in one go. It will avoid recomputing for each task, wasting a lot of time.

You can write the codes in a simple manner and modules. You can use any of Ember’s APIs. It is possible due to the presence of Promises everywhere.

Ember comes with a well-written guide. The API is recorded in a useful manner. It is a front-end framework that is loaded. Ember has a router, pipeline, services, etc. of its own.

The basis for views, controllers, models, and framework is the Ember Object Model. All components come from the same objects. The framework is firm and steady. The reason is that all elements have similar jobs and characteristics.

Ember has made the general application, organization, and structure clear so that you don’t make any mistakes. You will have no chance to complicate the application unnecessarily. If you have to go out of the defined limits, you will have to force your way out.

The language used for templating in Embers is Handlebars. This language helps Embers to keep its logic out of view. The clean syntax of Handlebars makes it easy for you to read and understand the templates. Handlebar templates are faster to load.

Another advantage you gain from Handlebar is that you don’t have to update your template every time you add or remove data from the page. It will be done automatically by the language itself.

A community that is continually improving the framework supports Ember. They are updating the framework with the latest technology. They also make sure that backward compatibility is possible.

● Ember.js is an open-source MVVM model framework suitable for complex multiple-page applications.

● It offers both the latest and old features.

● It has a very tightly structured framework which doesn’t offer much flexibility

● A very refined control system helps you to integrate with new versions without any problem.

● There is strict guidance about avoiding outdated API versions.

● Ember’s APIs help you to use complex functionalities in a simple manner

● There is no recomputing for each task as the framework allows the browser to do similar functions together.

● Promises allow you to write modular and straightforward code using any API of Ember.js.

● Ember.js is a fully loaded, front-end framework.

● The framework is stable because all components have the same functionalities and properties.

● It has well-defined limitations which will prevent your complicating your application

● Handlebars, the language used by Ember.js allows you to read and understand templates easily. It also helps to load the templates faster.

● Handlebars will ensure to update the template every time you add or remove data.

● Ember.js has an active community that updates the framework regularly and facilitates backward compatibility.

A Comparison Between Ember.js And Vue.js

This article intends to compare the features of both frameworks. Let us see how the characteristics of these frameworks compare. It will help you to make use of the right framework for your web application.

When you need a modern engine for an old application, it is Vue.js which will help you. It combines the best properties of other frameworks. Vue.js is a developing framework. A ready-to-use library of interface elements does not exist. However, many third-party libraries can help you.

Ember.js offers you a well-organized and trustworthy framework. When the development team is big, this is the framework that suits best. It allows everyone to understand the written code and contribute to a common project. The technology will be up-to-date, and the platform will be stable.

Vue.js can help you use the syntax of different kinds. It helps in writing the codes with ease. It is also an SEO friendly framework. Ember is a fully loaded front-end framework and can help you develop the applications very fast. But it is not suitable for developing small projects.

It is not easy to say this is better than that. It will depend on what kind of project you have undertaken. Both have their pluses and minuses. The below table will help in a better comparison.

Final Thoughts

It is not easy to conclude as to which is better. It all depends on the application that you want to develop. Both frameworks are developing. Both are getting updates. Both the communities are working on the frameworks.

While Vue.js is more comfortable for writing codes, Ember is a full-stack framework allowing the development of apps very fast. It is suitable for big projects. It is too complicated to be used for smaller projects.

We hope you had a great time reading this article. If you’ve any questions or suggestions related to this blog, then feel free to ask them in the comment section. Thank You.!