Accessibility in Vue Dialog

02 Sep 202612 minutes to read

The Dialog component follows the accessibility guidelines and standards, including ADA, Section 508, WCAG 2.2 standards, and WCAG roles that are commonly used to evaluate accessibility.

The accessibility compliance for the Dialog component is outlined below.

Accessibility Criteria Compatibility
WCAG 2.2 Support Yes
Section 508 Support Yes
Screen Reader Support Yes
Right-To-Left Support Yes
Color Contrast Yes
Mobile Device Support Yes
Keyboard Navigation Support Yes
Accessibility Checker Validation Yes
Axe-core Accessibility Validation Yes
Yes - All features of the component meet the requirement.
Intermediate - Some features of the component do not meet the requirement.
No - The component does not meet the requirement.

WAI-ARIA attributes

The Dialog is characterized with complete ARIA accessibility support which helps it be accessible by on-screen readers and other assistive technology devices. This component is designed with reference to the guidelines document given in WAI-ARIA Accessibility Practices.

The Dialog component uses the Dialog role and following ARIA properties to its element based on its state.

Property Functionalities
aria-describedby It indicates the Dialog content description is notified to the user through assistive technologies.
aria-labelledby The Dialog title is notified to the user through assistive technologies.
aria-modal For modal Dialog its value is true and non-modal Dialog its value is false.
aria-grabbed Enable the draggable Dialog and starts dragging its value is true and stops dragging its value is false.

Keyboard interaction

Keyboard interaction of the Dialog component is designed based on WAI-ARIA Practices described for Dialog. User can use the following shortcut keys to interact with the Dialog.

Keyboard shortcuts Actions
Esc Closes the Dialog. This functionality can be controlled by using `closeOnEscape`
Enter When the Dialog button or any input (except text area) is in focus state, when pressing the Enter key, the click event associated with the primary button will trigger. Enter key is not working when the Dialog content contains any text area with initial focus.
Ctrl + Enter When the Dialog content contains text area and it is in focus state, and press the Ctrl + Enter key to call the click event function associated with primary button.
Tab Focus will be changed within the Dialog elements.
Shift + Tab The Focus will be changed previous focusable element within the Dialog elements. When focusing a first focusable element in the Dialog, then press the shift + tab key, it will change the focus to last focusable element.
<template>
    <div>
        <div id="target" class="control-section; position:relative" style="height:350px;">

            <ejs-button id='modalbtn' v-on:click="btnClick">Open</ejs-button>

            <ejs-dialog ref="accessDialog" :header='header' :target='target' :width='width' :height='height'
                :showCloseIcon='true' :buttons='buttons' :content='content' :open="dlgOpen" :close="dlgClose">
            </ejs-dialog>
        </div>
    </div>
</template>
<script setup>

import { DialogComponent as EjsDialog } from '@syncfusion/ej2-vue-popups';
import { ButtonComponent as EjsButton } from '@syncfusion/ej2-vue-buttons';
import { onMounted, ref } from 'vue';

const accessDialog = ref(null);
const target = '#target';
const width = '335px';
const height = '350px';
const header = 'Feedback';
const content = "<form><div class='form-group'><label for='email'>Email:</label>" +
    "<input type='email' class='form-control' id='email'>" +
    "</div><div class='form-group'>" +
    "</div><div class='form-group'><label for='comment'>Comments:</label>" +
    "<textarea style='resize: none;' class='form-control' rows='4' id='comment'></textarea>" +
    "</div>" +
    "</form>";

onMounted(() => {
    document.getElementById('modalbtn').focus();
});
const btnClick = () => {
    accessDialog.value.show();
};
const dlgClose = () => {
    document.getElementById('modalbtn').style.display = '';
};
const dlgOpen = () => {
    document.getElementById('modalbtn').style.display = 'none';
};
const dlgButtonClick = () => {
    accessDialog.value.hide();
};
const buttons = [{ click: dlgButtonClick, buttonModel: { content: 'OK', isPrimary: true } },
{ click: dlgButtonClick, buttonModel: { content: 'Cancel' } }];

</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-popups/styles/material.css";
@import "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css";

#app {
    color: #008cff;
    height: 40px;
    left: 45%;
    position: absolute;
    top: 45%;
    width: 30%;
}

.control-section {
    height: 100%;
    min-height: 200px;
}
</style>
<template>
    <div>
        <div id="target" class="control-section; position:relative" style="height:350px;">

            <ejs-button id='modalbtn' v-on:click="btnClick">Open</ejs-button>

            <ejs-dialog ref="accessDialog" :header='header' :target='target' :width='width' :height='height'
                :showCloseIcon='true' :buttons='buttons' :content='content' :open="dlgOpen" :close="dlgClose">
            </ejs-dialog>
        </div>
    </div>
</template>
<script>

import { DialogComponent } from '@syncfusion/ej2-vue-popups';
import { ButtonComponent } from '@syncfusion/ej2-vue-buttons';

export default {
    name: "App",
    components: {
        "ejs-button": ButtonComponent,
        "ejs-dialog": DialogComponent
    },
    data: function () {
        return {
            target: '#target',
            width: '335px',
            height: '350px',
            header: 'Feedback',
            content: "<form><div class='form-group'><label for='email'>Email:</label>" +
                "<input type='email' class='form-control' id='email'>" +
                "</div><div class='form-group'>" +
                "</div><div class='form-group'><label for='comment'>Comments:</label>" +
                "<textarea style='resize: none;' class='form-control' rows='4' id='comment'></textarea>" +
                "</div>" +
                "</form>",
            buttons: [{ click: this.dlgButtonClick, buttonModel: { content: 'OK', isPrimary: true } },
            { click: this.dlgButtonClick, buttonModel: { content: 'Cancel' } }]
        }
    },
    mounted: function () {
        document.getElementById('modalbtn').focus();
    },
    methods: {
        btnClick: function () {
            this.$refs.accessDialog.show();
        },
        dlgClose: function () {
            document.getElementById('modalbtn').style.display = '';
        },
        dlgOpen: function () {
            document.getElementById('modalbtn').style.display = 'none';
        },
        dlgButtonClick: function () {
            this.$refs.accessDialog.hide();
        }
    }
}
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-popups/styles/material.css";
@import "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css";

#app {
    color: #008cff;
    height: 40px;
    left: 45%;
    position: absolute;
    top: 45%;
    width: 30%;
}

.control-section {
    height: 100%;
    min-height: 200px;
}
</style>

Ensuring accessibility

The Dialog component’s accessibility is validated using the accessibility-checker and axe-core tools during automated testing.

The accessibility compliance of the Dialog component is shown in the following sample. Open the sample in a new window to evaluate the accessibility of the Dialog component with accessibility tools.

See also