Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit bf8718e

Browse files
author
Marcy Sutton
committed
docs(guide/accessibility): Add in-depth guide
1 parent ce20dd0 commit bf8718e

File tree

1 file changed

+90
-29
lines changed

1 file changed

+90
-29
lines changed

docs/content/guide/accessibility.ngdoc

Lines changed: 90 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,56 +6,117 @@
66

77
# Accessibility with ngAria
88

9-
You can use the `ngAria` module to have common ARIA attributes automatically applied when you
10-
use certain directives. To enable `ngAria`, just require the module into your application and
11-
the code will hook into your ng-show/ng-hide, input, textarea, button, select and
12-
ng-required directives and add the appropriate ARIA states and properties.
9+
The goal of ngAria is to improve Angular's default accessibility by enabling common [ARIA](http://www.w3.org/TR/wai-aria/) attributes that convey state or semantic information for assistive technologies used by persons with disabilities.
10+
11+
##Including ngAria
12+
13+
Using ngAria is as simple as requiring the ngAria module in your application. ngAria hooks into standard AngularJS directives and quietly injects accessibility support into your application at runtime.
14+
15+
```js
16+
angular.module('myApp', ['ngAria'])...
17+
```
18+
19+
Currently, ngAria interfaces with the following directives:
20+
21+
* <a href="#ngmodel">ngModel</a>
22+
* <a href="#ngdisabled">ngDisabled</a>
23+
* <a href="#ngshow">ngShow</a>
24+
* <a href="#nghide">ngHide</a>
25+
* <a href="#ngclick-and-ngdblclick">ngClick</a>
26+
* <a href="#ngclick-and-ngdblclick">ngDblClick</a>
27+
28+
<h2 id="ngmodel">ngModel</h2>
29+
30+
Most of ngAria's heavy lifting happens in the [ngModel](https://docs.angularjs.org/api/ng/directive/ngModel) directive. For elements using ngModel, special attention is paid by ngAria if that element also has a a role or type of `checkbox`, `radio`, `range` or `textbox`.
31+
32+
For those elements using ngModel, ngAria will dynamically bind and update the following ARIA attributes (if they have not been explicitly specified by the developer):
1333

14-
Currently, the following attributes are implemented:
15-
* aria-hidden
1634
* aria-checked
17-
* aria-disabled
18-
* aria-required
19-
* aria-invalid
20-
* aria-multiline
21-
* aria-valuenow
2235
* aria-valuemin
2336
* aria-valuemax
24-
* tabindex
25-
26-
You can disable individual attributes by using the `{@link ngAria.$ariaProvider#config config}` method.
37+
* aria-valuenow
38+
* aria-invalid
39+
* aria-required
2740

2841
###Example
2942

30-
```js
31-
angular.module('myApp', ['ngAria'])...
43+
```html
44+
<md-checkbox ng-model="val" required>
3245
```
3346

34-
Elements using `ng-model` with `required` or `ngRequired` directives will automatically have
35-
`aria-required` attributes with the proper corresponding values.
47+
Becomes:
3648

3749
```html
38-
<material-input ng-model="val" required>
50+
<md-checkbox ng-model="val" required aria-required="true" tabIndex="0">
51+
```
52+
53+
ngAria will also add `tabIndex`, ensuring custom elements with these roles will be reachable from the keyboard. It is still up to **you** as a developer to **ensure custom controls will be operable** from the keybard. Think of `ng-click` on a `<div>` or `<md-checkbox>`: you still need to bind `ng-keypress` to make it fully operable from the keyboard. As a rule, any time you create a widget involving user interaction, be sure to test it with your keyboard and at least one mobile and desktop screen reader (preferably more).
54+
55+
<h2 id="ngdisabled">ngDisabled</h2>
56+
57+
The `disabled` attribute is only valid for certain elements such as `button`, `input` and`textarea`. To properly disable custom element directives such as `<md-checkbox>` or `<taco-tab>`, using ngAria with [ngDisabled](https://docs.angularjs.org/api/ng/directive/ngDisabled) will also add `aria-disabled`. This tells assistive technologies when a non-native input is disabled, helping custom controls to be more accessible.
58+
59+
###Example
60+
61+
```html
62+
<md-checkbox ng-disabled="disabled">
3963
```
4064

4165
Becomes:
4266

4367
```html
44-
<material-input ng-model="val" required aria-required="true">
68+
<md-checkbox disabled aria-disabled="true">
4569
```
4670

47-
ngAria is just a starting point. You'll have to manually choose how to implement some
48-
accessibility features.
71+
>You can check whether a control is legitimately disabled for a screen reader by visiting [chrome://accessibility](chrome://accessibility).
4972

50-
For instance, you may want to add `ng-keypress` bindings alongside `ng-click` to make keyboard
51-
navigation easier.
73+
<h2 id="ngshow">ngShow</h2>
5274

75+
>The [ngShow](https://docs.angularjs.org/api/ng/directive/ngShow) directive shows or hides the given HTML element based on the expression provided to the `ngShow` attribute. The element is shown or hidden by removing or adding the `.ng-hide` CSS class onto the element.
5376

54-
## Additional Resources
77+
In its default setup, ngAria for `ngShow` is actually redundant. It toggles `aria-hidden` on the directive when it is hidden or shown. However, the default CSS of `display: none !important`, already hides child elements from a screen reader. Where it becomes useful is when the default CSS is overridden with properties that don’t affect assistive technologies, such as `opacity` or `transform`. By toggling `aria-hidden` dynamically with ngAria, we can ensure content visually hidden with this technique will not be read aloud in a screen reader.
78+
79+
One caveat with this combination of CSS and `aria-hidden`: you must also remove links and other interactive child elements from the tab order using `tabIndex=“-1”` on each control. This ensures screen reader users won't accidentally focus on "mystery elements". Managing tab index on every child control can be complex and affect performance, so it’s best to just stick with the default `display: none` CSS. See the [fourth rule of ARIA use](http://www.w3.org/TR/aria-in-html/#fourth-rule-of-aria-use).
80+
81+
<h2 id="nghide">ngHide</h2>
82+
83+
>The [ngHide](https://docs.angularjs.org/api/ng/directive/ngHide) directive shows or hides the given HTML element based on the expression provided to the `ngHide` attribute. The element is shown or hidden by removing or adding the `.ng-hide` CSS class onto the element.
84+
85+
The default CSS for `ngHide`, the inverse method to `ngShow`, makes ngAria redundant. It toggles `aria-hidden` on the directive when it is hidden or shown, but the content is already hidden with `display: none`. See explanation for <a href="#ngshow">ngShow</a> when overriding the default CSS.
86+
87+
<h2 id="ngclick">ngClick and ngDblClick</h2>
88+
If `ngClick` or `ngDblClick` is encountered, ngAria will add `tabIndex` if it isn't there already. Even with this, you must currently still add `ng-keypress` to non-interactive elements such as `<div>` or `<taco-button>` to enable keyboard access. I have recommended this also bind `ng-keypress` to be more useful; the conversation is [currently ongoing](https://github.com/angular/angular.js/issues/9254).
89+
90+
* * *
91+
92+
##Disabling attributes
93+
The attribute magic of ngAria may not work for every scenario. To disable individual attributes, you can use the `{@link ngAria.$ariaProvider#config config}` method:
94+
95+
```
96+
angular.module('myApp', ['ngAria'], function config($ariaProvider) {
97+
$ariaProvider.config({
98+
tabindex: false
99+
});
100+
});
101+
```
102+
* * *
103+
104+
##Common Accessibility Patterns
55105

56106
Accessibility best practices that apply to web apps in general also apply to Angular.
57107

58-
* [A11Y Project](http://a11yproject.com/)
59-
* [WebAim](http://webaim.org/)
60-
* [Using WAI-ARIA in HTML](http://www.w3.org/TR/2014/WD-aria-in-html-20140626/)
61-
* [Apps For All: Coding Accessible Web Applications](https://shop.smashingmagazine.com/apps-for-all-coding-accessible-web-applications.html)
108+
* **Text alternatives**: Add alternate text content to make visual information accessible using [these W3C guidelines](http://www.w3.org/TR/html-alt-techniques/). The appropriate technique depends on the specific markup but can be accomplished using offscreen spans, `aria-label` or label elements, image `alt` attributes, `figure`/`figcaption` elements and more.
109+
* **HTML Semantics**: If you're creating custom element directives, Web Components or HTML in general, use native elements wherever possible to utilize built-in events and properties. Alternatively, use ARIA to communicate semantic meaning. See [notes on ARIA use](http://www.w3.org/TR/aria-in-html/#notes-on-aria-use-in-html).
110+
* **Focus management**: Guide the user around the app as views are appended/removed. Focus should *never* be lost, as this causes unexpected behavior and much confusion (referred to as "freak-out mode").
111+
* **Announcing changes**: When filtering or other UI messaging happens away from the user's focus, notify with [ARIA Live Regions](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions).
112+
* **Color contrast and scale**: Make sure content is legible and interactive controls are usable at all screen sizes. Consider configurable UI themes for people with color blindness, low vision or other visual impairments.
113+
* **Progressive enhancement**: Some users do not browse with JavaScript enabled or do not have the latest browser. An accessible message about site requirements can inform users and improve the experience.
114+
115+
## Additional Resources
116+
117+
* [Using ARIA in HTML](http://www.w3.org/TR/aria-in-html/)
118+
* [AngularJS Accessibility at ngEurope](https://www.youtube.com/watch?v=dmYDggEgU-s&list=UUEGUP3TJJfMsEM_1y8iviSQ)
119+
* [Chrome Accessibility Developer Tools](https://chrome.google.com/webstore/detail/accessibility-developer-t/fpkknkljclfencbdbgkenhalefipecmb?hl=en)
120+
* [W3C Accessibility Testing](http://www.w3.org/wiki/Accessibility_testing)
121+
* [WebAIM](http://webaim.org)
122+
* [A11y Project](http://a11yproject.com)

0 commit comments

Comments
 (0)