12 Develop Accessible Oracle JET Apps

Oracle JET and Oracle JET components have built-in accessibility features for people with disabilities. Use these features to create accessible Oracle JET web app pages.

About Oracle JET and Accessibility

Oracle JET components have built-in accessibility support that conforms with the Web Content Accessibility Guidelines version 2.2 at the AA level (WCAG 2.2 AA), developed by the World Wide Web Consortium (W3C).

Accessibility involves making your app usable for people with disabilities such as low vision or blindness, deafness, or other physical limitations. This means, for example, creating apps that can be:

  • Used without a mouse (keyboard only)

  • Used with assistive technologies such as screen readers and screen magnifiers

  • Used without reliance on sound, color, animation, or timing

Oracle JET components provide support for:

  • Keyboard and touch navigation

    Oracle JET components follow the Web Accessibility Initiative - Accessible Rich Internet Application (WAI-ARIA) Developing a Keyboard Interface guidelines. Follow these guidelines when using Oracle JET components in your app. For example, avoid setting tabindex to values greater than 0. The API documentation for each Oracle JET component lists its keyboard and touch end user information when applicable, including a few deviations from the WAI-ARIA guidelines.

  • Zoom

    Oracle JET supports browser zooming up to 400%. For example, on the Firefox browser, you can choose View -> Zoom -> Zoom In.

  • Screen reader

    Oracle JET supports screen readers such as JAWS, Apple VoiceOver, and Google TalkBack by generating content that complies with WAI-ARIA standards, and no special mode is needed.

  • Oracle JET component roles and names

    Each Oracle JET component has an appropriate role, such as button, link, and so on, and each component supports an associated name (label), if applicable.

  • Sufficient color contrast

    Oracle JET provides the Redwood theme, starting in Oracle JET release 9.0.0, which is designed to provide a luminosity contrast ratio of at least 4.5:1.

Oracle JET does not support the use of access keys due to their negative impact on assistive tooling and accessibility.

Oracle documents the degree of conformance of each product with the applicable accessibility standards using the Voluntary Product Accessibility Template (VPAT). You should review the appropriate VPAT for the version of Oracle JET that you are using for important information including known exceptions and defects, if any.

While Oracle JET is capable of rendering an app that conforms to WCAG 2.2 AA to the degree indicated by the VPAT, it is the responsibility of the app designer and developer to understand the applicable accessibility standards fully, use Oracle JET appropriately, and perform accessibility testing with disabled users and assistive technology.

About the Accessibility Features of Oracle JET Components

Oracle JET components are designed to generate content that conforms to the WCAG 2.2 AA standards. In most cases, you don't need to do anything to add accessibility to the Oracle JET component. However, there are some components where you may need to supply a label or other property.

For those components, the component's API documentation contains an Accessibility section that provides the information you need to ensure the component's accessibility.

Note:

Some Oracle products have runtime accessibility modes that render content optimized for certain types of users, such as users of screen readers. For the most part, Oracle JET renders all accessibility-related content all of the time. There is only a mode for users that rely on the operating system's high contrast mode, which is described in Create Accessible Oracle JET Pages.

Oracle JET components that provide keyboard and touch navigation list the keystroke and gesture end user information in their API documentation. Since the navigation is built into the component, you do not need to do anything to configure it.

You can access an individual Oracle JET component's accessibility features and requirements in the API Reference for Oracle® JavaScript Extension Toolkit (Oracle JET). Select the component you're interested in from the list on the left. You can also find the list of supported keystrokes and gestures for each Oracle JET component that supports keystrokes and gestures in the Oracle® JavaScript Extension Toolkit (JET) Keyboard and Touch Reference.

Create Accessible Oracle JET Pages

Content generated by Oracle JET is designed to conform to the WCAG 2.2 AA standards. However, many standards are not under the complete control of Oracle JET, such as overall UI consistency, the use of color, the quality of on-screen text and instructions, and so on.

A complete product development plan that addresses accessibility should include proper UI design, coding, and testing with an array of tools, assistive technology, and disabled users.

Note:

In most cases, end-user documentation for your app must describe information about accessibility, such as example keystrokes needed to operate certain components.

Configure WAI-ARIA Landmarks

WAI-ARIA landmarks provide navigational information to assistive technology users. Landmark roles identify the purpose of a page region and allow the user to navigate directly to a desired region. Without landmarks, assistive technology users must use the TAB key to navigate through a page.

The Oracle JET team recommends the use of WAI-ARIA landmarks to ensure page accessibility and provides examples you can use in the Oracle JET Starter Template collection. The following figure shows the runtime view of the Oracle JET Web Nav Drawer Starter Template (navdrawer). In this example, the page is organized into regions compatible with WAI-ARIA landmark regions, including regions for the banner, navigation, main, and contentinfo landmarks.

The code in the following example shows the landmarks for the navdrawer template. Each landmark is placed on the HTML element that defines the landmark region: div for the navigation regions, header for the banner region, oj-module for the main region, and footer for the contentinfo region.

<!DOCTYPE html>
<html lang="en-us">
  <head>
    <title>Oracle JET Starter Template - Web Nav Drawer</title>
    ...contents omitted
  </head>

  <body class="oj-web-applayout-body">
    ...contents omitted

    <div id="globalBody" class="oj-offcanvas-outer-wrapper oj-offcanvas-page">
      <div
        id="navDrawer"
        role="navigation"
        class="oj-contrast-marker oj-web-applayout-offcanvas oj-offcanvas-start">
        <oj-navigation-list
          id="navDrawerList"
          data="[[navDataProvider]]"
          item.renderer="[[KnockoutTemplateUtils.getRenderer('navTemplate', true)]]"
          on-click="[[toggleDrawer]]"
          selection="{{selection.path}}"></oj-navigation-list>
      </div>
      <div id="pageContent" class="oj-web-applayout-page">
        <header role="banner" class="oj-web-applayout-header">
          <div
            class="oj-web-applayout-max-width oj-flex-bar oj-sm-align-items-center">
            ...contents omitted
          </div>
          <div
            role="navigation"
            class="oj-web-applayout-max-width oj-web-applayout-navbar">
            <oj-tab-bar
              id="navTabBar"
              class="oj-sm-only-hide oj-md-condense oj-md-justify-content-flex-end"
              data="[[navDataProvider]]"
              edge="top"
              item.renderer="[[oj.KnockoutTemplateUtils.getRenderer('navTemplate', true)]]"
              selection="{{selection.path}}"></oj-tab-bar>
          </div>
        </header>
        <oj-module
          role="main"
          class="oj-web-applayout-max-width oj-web-applayout-content"
          config="[[moduleAdapter.koObservableConfig]]"></oj-module>

        <footer class="oj-web-applayout-footer" role="contentinfo">
          ...contents omitted
        </footer>
      </div>
    </div>
   ...contents omitted
  </body>
</html>

If your app includes a complementary region, add role="complementary" to the HTML div element:

<div role="complementary"></div>

For additional information about WAI-ARIA landmark roles, see landmark_roles.

Configure High Contrast Mode

High contrast mode is for people who require a very high level of contrast in order to distinguish components on the page. Operating systems such as Microsoft Windows and macOS provide methods for users to run in high contrast mode.

The graphic below shows the effect of changing to high contrast mode on Oracle JET icon font images.

Understand Color and Background Image Limitations in High Contrast Mode

There are color and background image limitations in high contrast mode that your app may need to work around.

In high contrast mode the colors in the CSS may be ignored or overridden, including background, border, and text colors. Therefore, in high contrast mode you may need to find an alternative way to show state. For example, you might need to add or change the border to show that something is selected. To change CSS in high contrast mode, see forced-colors.

Also, your app may need to show alternate high contrast images that work on either a dark or light background color. Consider providing an image that includes a background, so either black on a white background or white on a black background. That way it won’t matter what the background color is on the page since the contrast is in the image itself.

Test High Contrast Mode

The recommended way to test high contrast mode in Oracle JET app is to set high contrast mode at the operating system level and test your app in browsers that support high contrast mode, such as Google Chrome, Microsoft Edge, and Mozilla Firefox.

For information about enabling high contrast mode, see the documentation for your computer’s operating system. For example, to turn high contrast mode on and off in Microsoft Windows, use the following key combination: Left Alt+Left Shift+PrtScn. You may need to refresh your browser to see the new mode.

Hide Screen Reader Content

Sometimes you want to have some text on the page that is read to the screen reader user, but the sighted user doesn't see. Oracle JET provides the oj-helper-hidden-accessible class that you can use to hide content.

You can find the .oj-helper-hidden-accessible style defaults in the Redwood theme CSS file (web/css/redwood/x.x.x/web/redwood.css). For additional information about theming and Oracle JET, see Use CSS and Themes in Oracle JET Apps.

Use ARIA Live Region

An ARIA live region is a mechanism to notify assistive technologies when a web page content is updated.

When using a single page app, if there are any changes to the page or the page region, the user of assistive technologies, such as screen readers, is not notified about the changes in the page content since the URL of the app has not changed. To help provide a notification to the screen readers when a page or segments of a page change, an ARIA live region announces the dynamic changes within a web page. When the update takes place within an ARIA live region, a screen reader is automatically notified, wherever its focus is at the time, and it announces the updated content to the user. This can be achieved by using the aria-live attribute.

The aria-live attribute identifies an element as a live region. It takes three possible values:

  • off: No notification

  • polite: Screen reader notifies user once the current task is complete

  • assertive: Screen reader interrupts the current task to notify user

If the value of the aria-live attribute defined for an element is set to polite, your screen reader will not be interrupted and will announce the changes in the ARIA live region when the user has no activity on the screen. If the value is set to assertive, the new information has high priority and should be notified or announced to the user immediately.

You can also use some of the advanced ARIA live region attributes to communicate information about the entire live region or a portion of the live region to assistive technologies. Some of the advanced live region attributes to use are:

  • aria-atomic: The aria-atomic attribute is used along with aria-live attribute when the page contains live regions. This attribute is used to set whether the assistive technologies should present the entire live region as a single unit or to only announce the regions that have been changed. The possible values are true or false. The default value is false.

  • aria-relevant: This attribute is used in conjunction with the aria-live attribute to describe the types of changes that have occurred within a given live region that should be announced to the user. The possible settings are additionsremovalstext, and all. The default setting is additions text.

The following example an ARIA live region defined in the index.html file of an Oracle JET app created with the navdrawer template. In this example, the aria-live attribute is set to assertive and the aria-atomic attribute is set to true:

. . . 
<div id="globalBody">
  <div id="announce" tabindex="-1" 
       class="send-off-screen" 
       :aria-live="[[manner]]" aria-atomic="true">
	<p id="ariaLiveMessage"><oj-bind-text value="[[message]]"></oj-bind-text></p>
  </div>
. . .

The following example shows how to set up the observables and event listeners in the appController file of the app.

. . .
class RootViewModel {
  manner: ko.Observable<string>;
  message: ko.Observable<string | undefined>;
  . . .

  constructor() {
    // handle announcements sent when pages change, for Accessibility.
    this.manner = ko.observable('polite');
    this.message = ko.observable();

    let globalBodyElement: HTMLElement = document.getElementById(
      'globalBody'
    ) as HTMLElement;
    globalBodyElement.addEventListener(
      'announce',
      this.announcementHandler,
      false
    );
. . . 
function ControllerViewModel() {
. . . 

  // Handle announcements sent when pages change, for Accessibility.
  this.manner = ko.observable('polite');
  this.message = ko.observable();
  announcementHandler = (event) => {
    this.message(event.detail.message);
    this.manner(event.detail.manner);
  };

 document
  .getElementById('globalBody')
  .addEventListener('announce', announcementHandler, false);

By default, each of the Oracle JET apps that you scaffold with a starter template (for example, navdrawer) include an accessibility utility module that defines a function (announce) to send an announcement to an Aria Live region. This module is in the ts or js sub-directory of your appRootDir/src directory, depending on whether your app is TypeScript or JavaScript-based. An example usage is also implemented in each of the generated modules (dashboard, for example) of the Oracle JET app.

. . .
import * as AccUtils from '../accUtils';

class DashboardViewModel {
  constructor() {}
  connected(): void {
    AccUtils.announce('Dashboard page loaded.');
    document.title = 'Dashboard';
    // implement further logic if needed
  }
. . .
define(['../accUtils'], function (accUtils) {

  function DashboardViewModel() {

    this.connected = () => {
      accUtils.announce('Dashboard page loaded.', 'assertive');
      document.title = 'Dashboard';
      // Implement further logic if needed
    };
. . .