+
diff --git a/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-control.component.ts b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-control.component.ts
new file mode 100644
index 0000000000..a62782d9ba
--- /dev/null
+++ b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-control.component.ts
@@ -0,0 +1,68 @@
+import {Component, OnInit, Provider, forwardRef,} from "angular2/core";
+import {A11yHelper} from "../services/a11y-helper.service";
+import {NG_VALUE_ACCESSOR, ControlValueAccessor} from "angular2/common";
+
+// #docregion
+const noop = () => {
+};
+
+const A11Y_CUSTOM_CONTROL_VALUE_ACCESSOR = new Provider(
+ NG_VALUE_ACCESSOR, {
+ useExisting: forwardRef(() => A11yCustomControl),
+ multi: true
+ });
+
+@Component({
+ selector: 'a11y-custom-control',
+ templateUrl: './app/shared/a11y-custom-control.component.html',
+ styleUrls: ['./app/shared/a11y-custom-control.component.css'],
+ providers: [A11Y_CUSTOM_CONTROL_VALUE_ACCESSOR]
+})
+export class A11yCustomControl implements OnInit, ControlValueAccessor {
+
+ uniqueId:string;
+
+ private _innerValue:any = '';
+ outerValue:string = '';
+
+ private _onTouchedCallback:() => void = noop;
+ private _onChangeCallback:(_:any) => void = noop;
+
+ constructor(private _a11yHelper:A11yHelper) {
+ }
+
+ onChange(event:any, value:string) {
+ if (event.keyCode == 13) {
+ event.preventDefault();
+ }
+ else {
+ this._innerValue = this._a11yHelper.removeHtmlStringBreaks(value);
+ this._onChangeCallback(this._innerValue);
+ }
+ }
+
+ onBlur(){
+ this._onTouchedCallback();
+ }
+
+ writeValue(value:any) {
+ if (value != this._innerValue) {
+ this._innerValue = value;
+ this.outerValue = value;
+ }
+ }
+
+ registerOnChange(fn:any) {
+ this._onChangeCallback = fn;
+ }
+
+ registerOnTouched(fn:any) {
+ this._onTouchedCallback = fn;
+ }
+
+ ngOnInit():void {
+ this.uniqueId = this._a11yHelper.generateUniqueIdString();
+ }
+
+}
+// #enddocregion
diff --git a/public/docs/_examples/cb-a11y/ts/app/shared/a11y-value-helper.component.html b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-value-helper.component.html
new file mode 100644
index 0000000000..bde42e27d4
--- /dev/null
+++ b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-value-helper.component.html
@@ -0,0 +1,5 @@
+
+ Current value: {{displayValue}}
+
diff --git a/public/docs/_examples/cb-a11y/ts/app/shared/a11y-value-helper.component.ts b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-value-helper.component.ts
new file mode 100644
index 0000000000..6443299ec6
--- /dev/null
+++ b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-value-helper.component.ts
@@ -0,0 +1,18 @@
+import {Component, Input} from "angular2/core";
+
+@Component({
+ selector: 'a11y-value-helper',
+ templateUrl: './app/shared/a11y-value-helper.component.html',
+ styles: [`
+ .value-label {
+ position:relative;
+ top: -15px;
+ }
+`]
+})
+export class A11yValueHelper {
+
+ @Input()
+ displayValue: any;
+
+}
diff --git a/public/docs/_examples/cb-a11y/ts/example-config.json b/public/docs/_examples/cb-a11y/ts/example-config.json
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/public/docs/_examples/cb-a11y/ts/example-config.json
@@ -0,0 +1 @@
+
diff --git a/public/docs/_examples/cb-a11y/ts/index.html b/public/docs/_examples/cb-a11y/ts/index.html
new file mode 100644
index 0000000000..e56cff83f3
--- /dev/null
+++ b/public/docs/_examples/cb-a11y/ts/index.html
@@ -0,0 +1,42 @@
+
+
+
+
+ A11y demonstration
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+loading...
+
+
+
diff --git a/public/docs/_examples/cb-a11y/ts/plnkr.json b/public/docs/_examples/cb-a11y/ts/plnkr.json
new file mode 100644
index 0000000000..8e4e448188
--- /dev/null
+++ b/public/docs/_examples/cb-a11y/ts/plnkr.json
@@ -0,0 +1,8 @@
+{
+ "description": "A11y Cookbook samples",
+ "files":[
+ "!**/*.d.ts",
+ "!**/*.js"
+ ],
+ "tags":["cookbook", "a11y"]
+}
\ No newline at end of file
diff --git a/public/docs/dart/latest/cookbook/_data.json b/public/docs/dart/latest/cookbook/_data.json
index ce8315d497..3600c7ca08 100644
--- a/public/docs/dart/latest/cookbook/_data.json
+++ b/public/docs/dart/latest/cookbook/_data.json
@@ -4,14 +4,20 @@
"navTitle": "Overview",
"intro": "A collection of recipes for common Angular application scenarios"
},
-
+
"a1-a2-quick-reference": {
"title": "Angular 1 to 2 Quick Reference",
"navTitle": "Angular 1 to 2 Quick Ref",
"intro": "Learn how Angular 1 concepts and techniques map to Angular 2",
"hide": true
},
-
+
+ "a11y": {
+ "title": "ARIA / Accessibility (a11y) reference",
+ "navTitle": "ARIA / Accessibility (a11y)",
+ "intro": "Learn how to make your Angular 2 sites accessible for everyone"
+ },
+
"component-communication": {
"title": "Component Interaction",
"intro": "Share information between different directives and components"
@@ -22,7 +28,7 @@
"intro": "Techniques for Dependency Injection",
"hide": true
},
-
+
"dynamic-forms": {
"title": "Dynamic Form",
"intro": "Render dynamic forms with NgFormModel",
@@ -34,4 +40,4 @@
"intro": "Convert Angular 2 TypeScript examples into ES5 JavaScript",
"hide": true
}
-}
\ No newline at end of file
+}
diff --git a/public/docs/dart/latest/cookbook/a11y.jade b/public/docs/dart/latest/cookbook/a11y.jade
new file mode 100644
index 0000000000..e44128c6a2
--- /dev/null
+++ b/public/docs/dart/latest/cookbook/a11y.jade
@@ -0,0 +1,2 @@
+!= partial("../../../_includes/_ts-temp")
+
diff --git a/public/docs/js/latest/cookbook/_data.json b/public/docs/js/latest/cookbook/_data.json
index a2040caccf..38bcf23120 100644
--- a/public/docs/js/latest/cookbook/_data.json
+++ b/public/docs/js/latest/cookbook/_data.json
@@ -11,6 +11,12 @@
"intro": "Learn how Angular 1 concepts and techniques map to Angular 2"
},
+ "a11y": {
+ "title": "ARIA / Accessibility (a11y) reference",
+ "navTitle": "ARIA / Accessibility (a11y)",
+ "intro": "Learn how to make your Angular 2 sites accessible for everyone"
+ },
+
"component-communication": {
"title": "Component Interaction",
"intro": "Share information between different directives and components"
@@ -20,7 +26,7 @@
"title": "Dependency Injection",
"intro": "Techniques for Dependency Injection"
},
-
+
"dynamic-forms": {
"title": "Dynamic Form",
"intro": "Render dynamic forms with NgFormModel"
diff --git a/public/docs/js/latest/cookbook/a11y.jade b/public/docs/js/latest/cookbook/a11y.jade
new file mode 100644
index 0000000000..6778b6af28
--- /dev/null
+++ b/public/docs/js/latest/cookbook/a11y.jade
@@ -0,0 +1 @@
+!= partial("../../../_includes/_ts-temp")
diff --git a/public/docs/ts/latest/cookbook/_data.json b/public/docs/ts/latest/cookbook/_data.json
index e4363318ef..11d69c8e0c 100644
--- a/public/docs/ts/latest/cookbook/_data.json
+++ b/public/docs/ts/latest/cookbook/_data.json
@@ -4,13 +4,19 @@
"navTitle": "Overview",
"description": "A collection of recipes for common Angular application scenarios"
},
-
+
"a1-a2-quick-reference": {
"title": "Angular 1 to 2 Quick Reference",
"navTitle": "Angular 1 to 2 Quick Ref",
"intro": "Learn how Angular 1 concepts and techniques map to Angular 2"
},
-
+
+ "a11y": {
+ "title": "ARIA / Accessibility (a11y) reference",
+ "navTitle": "ARIA / Accessibility (a11y)",
+ "intro": "Learn how to make your Angular 2 sites accessible for everyone"
+ },
+
"component-communication": {
"title": "Component Interaction",
"intro": "Share information between different directives and components"
diff --git a/public/docs/ts/latest/cookbook/a11y.jade b/public/docs/ts/latest/cookbook/a11y.jade
new file mode 100644
index 0000000000..f021ac2381
--- /dev/null
+++ b/public/docs/ts/latest/cookbook/a11y.jade
@@ -0,0 +1,1080 @@
+include ../_util-fns
+
+:marked
+ ## Welcome to A11y!
+
+ You are about to learn how to make your Angular 2 application accessible for
+ as many people as possible. This is no small goal as there is a large group of people out there who find it
+ very hard or even impossible to use applications that have not been built with these concepts in mind.
+
+ We will show you how to integrate these concepts with little to no extra effort on your part,
+ provided you take them into account right from the design phase of your application.
+
+ So page through this cookbook, apply these recipes and watch your user base grow.
+
+ If you see the terms `Web Accessibility`, `ARIA` or `a11y` for the first time, you are at the start of an
+ incredible journey. For those who already enjoy the benefits of `Accessible Web Applications`, we will
+ show you how to use your knowledge in the new and exciting world of Angular 2.
+
+.l-main-section
+:marked
+ ## A11y and ARIA in a nutshell
+
+ `Accessibility` is often called `a11y`. This is because we want to say as lot while we write less. As
+ it has eleven letters, starts with an `a` and ends with a `y`, we shorten this word to `a11y`. We will
+ refer to `a11y` when we want to say `accessibility`.
+
+.l-sub-section
+ :marked
+ In short, `a11y` refers to creating web applications that everyone can use, making it accessible to everyone.
+
+:marked
+ If you are totally new to the term you may want to have a look at what the folks at the `W3C` have to say about
+ [a11y](https://www.w3.org/WAI/intro/accessibility.php), to put the rest of the article into perspective.
+
+ What is that other word?
+
+.l-sub-section
+ :marked
+ `ARIA`, or `Accessible Rich Internet Applications` refers to a standard set of attributes for adding accessibility
+ information to `HTML` and `SVG`, which allows us to bring `a11y` concepts into
+ Internet applications like those we are building with Angular 2.
+
+:marked
+ You can also read what they say about [ARIA](https://www.w3.org/WAI/intro/aria) at the `W3C`. We will be right here
+ waiting for you when you come back.
+
+.callout.is-important
+ header ARIA terminology confusion alert!
+ :marked
+ In `ARIA` we refer to the `aria-...` attributes as `ARIA States` or `ARIA Properties`. The difference between
+ the two should become clear as you progress through this cookbook. However, `ARIA Properties` are not
+ real `HTML` element properties but decorating attributes referring to properties. When we refer to an
+ `ARIA Property` in the code you will **HAVE** to do
+ it with an Angular 2 attribute binding. This is simply a terminology clash.
+
+.l-main-section
+:marked
+ ## Native elements vs. custom components
+
+ Angular 2 gives you a lot of power at your fingertips to create extremely powerful components. Spare a
+ thought for the native `HTML` elements before you decide to build something new.
+
+ The makers of the browsers have spent a lot of time thinking about the very same issue that brought
+ you to this page today and have provided you with a lot of functionality out-of-the-box when you make use of
+ native `HTML` elements.
+
+ We would like to suggest the following rule of thumb when building your applications:
+
+.l-sub-section
+ :marked
+ If there is already a native element inside `HTML` providing the function that you need, use
+ that element instead of writing your own.
+
+:marked
+ So, if you want to accept user text input, use the `input` element instead of constructing something new.
+
+ This way you have to think less about things like focus management, tabindex, etc. and have more time to think about
+ your code.
+
+ We know this is not always possible, so this guide will also show you what you can do to make your own
+ components as accessible as possible.
+
+ So without further ado, let us see how easy it is to get big `a11y` wins in our applications!
+
+.l-main-section
+:marked
+ ## Important note on styling in this chapter
+
+.callout.is-important
+ header Angular Pages Do Not Require A Style Library
+ :marked
+ Where you see `CSS` classes in the example code, these classes are independent of Angular 2. It does not need
+ the styles of any external library. We are free to style our apps with any `CSS library`, our own `Custom CSS` or use no
+ `CSS` at all.
+
+:marked
+ Classes like `container`, `row`, `col-xs-12`, `checkbox`, `radio`, `form-group`, `form-control`, etc,
+ come from [Twitter Bootstrap](http://getbootstrap.com/css/). This is a purely cosmetic addition to prettify
+ the examples so that they are as visually appealing as they are accessible.
+
+ Always remember, just because something looks good, it does not mean that it is accessible.
+
+ The good news is, here we strive to do both!
+
+.l-main-section
+
+:marked
+ ## Table of contents
+
+ [Accessible form control labels](#form-control-labels)
+
+ [Managing focus](#managing-focus)
+
+ [Roles for custom component widgets](#component-roles)
+
+.l-sub-section
+ :marked
+ In the example application code when we need unique element id's we will be generating `GUID's`to make sure that they are
+ unique. You can use your own method to do this, as long as every id on a page is unique. More on this later...
+
+:marked
+ **Feel free to follow along in this [live example](/resources/live-examples/cb-a11y/ts/plnkr.html)**.
+
+.l-main-section
+
+:marked
+ ## Accessible form control labels
+
+ Whether we are using native interactive `HTML` elements or creating our own rich custom interactive components,
+ it is crucial to
+ label them. Imagine coming face-to-face with a customer detail page on your favourite online store, and
+ be greeted with a screen filled with unlabeled input fields!
+
+ That would be a nightmare right? The users will leave so fast the bounce rate counter will be able to power a small town, it will be
+ spinning *THAT* fast.
+
+ We can avoid this from ever happening by simply adding a label for each field. The challenge is that
+ many users of our website will not be able to see or recognize these labels without help.
+
+ For this reason it is not only important to visually mark any form component, or `form controls` as they are sometimes called,
+ but to do so in a way that also exposes it to assistive technologies.
+
+ We will discuss some ways to do this.
+
+.l-sub-section
+ :marked
+ You will see the `ng-content` tag making its appearance in some examples. This is because we are making use
+ of `Content Projection` to load content into the templates of our components.
+
+.l-sub-section
+ :marked
+ It is very important to note that a `label` element can describe one and only form input element. You cannot
+ label multiple form fields with one label. However, this is something we can do with `ARIA`.
+
+.l-sub-section
+ :marked
+ The label text position also matters. For `inputs`, `textareas` and `selects`, the label text precedes
+ the element and for `checkboxes` and `radiobuttons`, the text should follow the element in the flow.
+
+:marked
+ ### Implicit labeling
+
+ Firstly we will look at the easiest, quickest way to give our form controls accessible labels,
+ and that is with a syntax called `implicit labeling`.
+
+.l-sub-section
+ :marked
+ Use this method to label your `form controls` when possible. As you will see later, the other methods of
+ labeling rely on generating unique id's for your elements. As we are often building reusable components
+ in Angular 2, you will need to make sure that every id you create is unique on a page, no matter how often you use
+ your component! Save yourself the trouble and label implicitly.
+
+:marked
+ We label implicitly like this:
+
+code-example(language="html" escape="html").
+
+
+:marked
+ Easy, isn't it? Of course, here we can substitute the `input` element with any native `HTML` form control.
+
+ Let us now explore how we can use `implicit labeling` to decorate the commonly used native `HTML` form controls
+ in our Angular 2 components.
+
+:marked
+ #### Inputs and textareas
+
+ Labeling an input:
+
++makeExample('cb-a11y/ts/app/form-controls/a11y-form-controls.component.html','cb-a11y-form-controls-input-implicit')
+
+:marked
+ Labeling a textarea:
+
++makeExample('cb-a11y/ts/app/form-controls/a11y-form-controls.component.html','cb-a11y-form-controls-textarea-implicit')
+
+:marked
+ #### Checkboxes and radiobuttons
+
+.l-sub-section
+ :marked
+ Because of the many `input` fields making up a `checkbox group` or `radiobutton group`, the usual rule applies
+ for each input but the entire group also needs labeling and we do this by using `fieldset` and `legend`.
+
+:marked
+ Labeling checkboxes:
+
++makeExample('cb-a11y/ts/app/form-controls/a11y-form-controls.component.html','cb-a11y-form-controls-checkboxes-implicit')
+
+:marked
+ Labeling radiobuttons:
+
++makeExample('cb-a11y/ts/app/form-controls/a11y-form-controls.component.html','cb-a11y-form-controls-radiobuttons-implicit')
+
+:marked
+ #### Select lists
+
++makeExample('cb-a11y/ts/app/form-controls/a11y-form-controls.component.html','cb-a11y-form-controls-select-implicit')
+
+:marked
+ ### Explicit labeling
+
+ There could be a number of reasons why you prefer not using the `implicit labeling` syntax described above. Maybe
+ you need to write the input outside the label for positioning or styling purposes, or maybe your elements are
+ already furnished with id's.
+
+ As an alternative, you can also use the `explicit labeling` syntax. For this syntax
+ the `HTML` form element needs an `id`, which is then connected via a `for / id` pair *[The `for` attribute of the label has to
+ match the `id` of the element being labeled]* .
+
+ As an example, we will only look at adding an `explicit label` to a `text input`. The examples under the `implicit labeling`
+ section can then easily be adjusted to use this syntax.
+
++makeExample('cb-a11y/ts/app/form-controls/a11y-form-controls.component.html', 'cb-a11y-form-controls-input-explicit')
+
+:marked
+ ### Hidden labels
+
+ Sometimes, the design of your page makes more sense without a visible label. Think about `search` fields. Do you have
+ to give a visual label for each one?
+
+ The answer is no, but does that mean we get away with not labeling those fields at all?
+
+ Again the answer is no.
+
+ So how do we solve it?
+
+ We can either use an `explicitly labeled` input and hide the label with style, or we can use `aria-label`, which
+ is an `ARIA Property`.
+
+.l-sub-section
+ :marked
+ We cannot hide the label using the `display` css property. Hidden fields are also hidden to assistive
+ technologies so we have to use some css magic to either place the label outside the visible page or
+ shrink it right down. We will not see it, but screen readers will still find it and read it while
+ still linking it to the correct input via the `for / id` linkup. The following example has such a
+ `visually hidden` style.
+
+:marked
+ Example of a good visually hidden css style:
+
++makeExample('cb-a11y/ts/a11y.css', 'cb-a11y-form-controls-visually-hidden-style')
+
+:marked
+ Applying the style to a control to hide the label:
+
++makeExample('cb-a11y/ts/app/form-controls/a11y-form-controls.component.html', 'cb-a11y-form-controls-hidden-label-explicit')
+
+:marked
+ Or the `aria-label` alternative:
+
++makeExample('cb-a11y/ts/app/form-controls/a11y-form-controls.component.html','cb-a11y-form-controls-hidden-label-aria')
+
+:marked
+ This `aria-label` attribute serves the same `a11y` purpose as our `label` tags above and tells screen readers the label
+ of the field.
+
+.l-sub-section
+ :marked
+ So why not simply always use `aria-label`? This is because adding the `label` element not only provides the visual
+ label, but linking a `label` to a `native form control` also means that clicking on the `label` will select the
+ `form control` itself. This assists users with motor disabilities by providing a larger clickable area, thereby also
+ touching on another important area of `a11y`.
+
+:marked
+ Let's have a look at a quick comparison between and `input` with no label versus one labeled with `aria-label`.
+
+ The following shows what happens if we have an `input` for filtering criteria that does not take any `a11y` into account. We will
+ use the accessibility tools in the newest development version of `Chrome`, although you can use one of a number of internal
+ and external web browser tools to test accessibility.
+
+ Here we see the information that assistive technologies will use when reading our field out:
+
+figure.image-display
+ img(src="/resources/images/cookbooks/a11y/invisible-label-input-not-labeled.png" alt="Input with invisible label not labeled correctly")
+
+:marked
+ The only description a user with a screen reader will get is **Enter a value**. What value?
+
+ Just imagine if there are more than one input on the same page with the same placeholder. Utter chaos!
+
+ Now let's get some `a11y` going there and look at the same input again:
+
+figure.image-display
+ img(src="/resources/images/cookbooks/a11y/invisible-label-input-labeled.png" alt="Input with invisible label labeled correctly")
+
+:marked
+ Immediately it is clear what this `input` field is all about and what to do with it!
+
+:marked
+ ### Labeling custom form controls
+
+ So you need to do something and try as you might you cannot construct it with native `HTML` elements
+ **OR** you need to give that legacy application an `a11y` makeover without the luxury of rewriting the
+ entire code base.
+
+ How would you go about making these custom form controls accessible?
+
+ Fear not, there is a way! We introduce the next addition to our `ARIA` toolkit, and that is `aria-labelledby`.
+
+ Wait, why do we even need this? We just use the `for / id` binding of the `label` element, right?
+
+ Wrong again! The `for / id` function of the `label` element is only recognized when used with
+ the native `HTML` form control elements such as `input` and `textarea`. To label anything else, like a `div` or a
+ `custom element` we need to create this link by using `aria-labelledby`.
+
+ Let's illustrate this by recreating the native `input` element with a component that makes use of `div's`.
+
+.l-sub-section
+ :marked
+ Please note that creating an `input` out of `div's` is **NOT** recommended, but only serves as an illustration that
+ it is possible to make any form control accessible. Also note that as we are focusing on `a11y`, our component is not
+ production ready but only
+ implements the basics of functionality to make it function as an `input`, for example adding the machinery to make it play nicely
+ with `ngModel`. The full implementation would become
+ even larger and more complex before we can use it in an enterprise application. We hope that this illustrates
+ further why native `HTML` elements should preferably be used.
+
+:marked
+ Our component:
+
++makeTabs('cb-a11y/ts/app/shared/a11y-custom-control.component.html,cb-a11y/ts/app/shared/a11y-custom-control.component.ts,cb-a11y/ts/app/shared/a11y-custom-control.component.css',
+null, 'a11y-custom-control.component.html,a11y-custom-control.component.ts, a11y-custom-control.component.css')
+
+:marked
+ This can now be used in our `HTML` as follows:
+
++makeExample('cb-a11y/ts/app/form-controls/a11y-form-controls.component.html','cb-a11y-form-controls-custom-control-usage')
+
+:marked
+ Let's have a look at what is rendered out. *For clarity sake, we omit the style attributes added by Angular 2
+ for the component style.*:
+
+code-example(language="html" escape="html" format="linenums").
+
+
+
+
+
+
+
+:marked
+ The first thing that we should note is the `role` attribute. This is also part of `ARIA` and we use these when we need
+ to tell assistive technologies that the semantic role of an `HTML` element has changed. The `div` element was certainly
+ never specified as a textbox! Here we are doing just that, so our custom control needs the role of
+ `textarea`. We will look at `ARIA Roles` in more detail later.
+
+ Next we will look at the `aria-labelledby` attribute. As you can see, this has the `id` of the `label` field. This
+ is how we tell screen readers to use that specific `label` element to label our input control.
+
+.l-sub-section
+ :marked
+ Besides the need to generate unique `id's`, there is one more warning in using `aria-labelledby`. Even when using this
+ with an actual `label` element, clicking the label will **NOT** focus the input as it does when used with native
+ `HTML` form control elements. Therefore, this construct will always be slightly inferior to the native approach, as you lose the
+ accessibility gain the `label click` gives you.
+
+:marked
+ We also snuck in yet another `ARIA` property called `aria-multiline`. Yes folks,
+ we need to tell someone who is unable to see if our input accepts single or multiple lines of text. By using
+ `aria-multiline`, we are able to tell the screen reader whether it is single or multiline field.
+
+ *That was certainly a mouthful! Aren't there ways where we can use the power of Angular 2, but keep the
+ built-in `a11y` wins the native `HTML` elements give us?*
+
+ There certainly are and let's look at one such option that uses `Content Projection`.
+
+:marked
+ ### Labeling options with Content Projection
+
+ One of the biggest wins in using Angular 2 components is that they are reusable. This means less code to write,
+ which makes everyone happy as it leads to a more maintainable code base and building
+ functionality quicker.
+
+ The syntax patterns we suggested earlier in this section could, of course, work against this very strength. Duplicating
+ all the `HTML` for each well styled and functional form control is not what we are aiming for either. Neither
+ are we suggesting throwing out all the power of Angular 2. Hey, we built it after all!
+
+ There are mechanisms inside Angular 2 which allows you to use what you have just learnt in clever ways to
+ gain the biggest wins with accessibility of your form controls, while also benefiting from using the framework.
+
+ As an example of what you could do, we will be looking at using `Content Projection` and `Implicit Labeling` to build
+ a component that can decorate any input:
+
++makeTabs('cb-a11y/ts/app/form-controls/a11y-input-wrapper.component.html,cb-a11y/ts/app/form-controls/a11y-input-wrapper.component.ts,cb-a11y/ts/app/form-controls/a11y-input-wrapper.component.css',
+null, 'a11y-input-wrapper.component.html,a11y-input-wrapper.component.ts, a11y-input-wrapper.component.css')
+
+:marked
+ How do we use it? Like this:
+
++makeExample('cb-a11y/ts/app/form-controls/a11y-form-controls.component.html','cb-a11y-form-controls-custom-control-wrapped-usage')
+
+:marked
+ Let's quickly dive into the code.
+
+ We used `Content Projection` with `multiple projection slots` to project our `input` and the `label` content into our component's
+ template. This way we keep direct access to and direct control of the `label` content as well as the `input`.
+
+ Our component gets to do all the hard work for us while we have got all the benefits of using the native `HTML input`
+ element directly!
+
+ We did not have to add any of the extra code of the previous component and our resultant decorated `input`
+ control is fully accessible.
+
+ With `a11y` in Angular 2 it truly seems that you can indeed have your cake.... and eat it!
+
+:marked
+ ### Section summary
+
+ In this section we looked at how we can give accessible labels to our native, as well as custom, form controls.
+
+ We looked at `implicit labeling` versus `explicit labeling` and how `implicit labeling` can often save you
+ a lot of extra lines of code and trouble.
+
+ We also saw that even when a control does not need a visual label, it still needs a label for those who
+ cannot see it and we looked at ways to hide these labels in an accessible way.
+
+ Finally, we looked at how we can label even the most inaccessible of controls with `ARIA` and how we could use
+ what lies in our Angular 2 toolbox in clever ways so that we could benefit from combining the raw power of
+ Angular 2 with the `a11y` implementations of native `HTML` elements.
+
+ Keep reading for more on `a11y` in Angular 2 or [go back to the table of contents](#toc)
+
+.l-main-section
+
+:marked
+ ## Managing focus
+
+ Often when developers think of `a11y`, they only think of people with visual disabilities and screen readers.
+
+ While we do a lot to make sure that screen readers can properly consume and read our pages, `a11y` is
+ about much, much more. Visual disabilities is only one of the main groups of disabilities that hamper access to the web.
+ There is also a vast group of people out there who finds it difficult to use our websites due to `motor disabilities`.
+
+ We need to spare a thought for those people out there who would love to use our shiny new Angular 2 application, but
+ simply cannot use a mouse due to a variety of reasons. Some people have no hands whilst others
+ are unable to use their hands temporarily, due to injury. Just like those with visual disabilities, this group also
+ relies strongly on the keyboard or other types of assistive technologies when they navigate the web.
+
+.l-sub-section
+ :marked
+ One of the most important aspects of `a11y` is called `keyboard accessibility`. This means that every page we make
+ **MUST** be navigable and operable through use of the keyboard alone.
+
+:marked
+ So how do `keyboard accessibility` relate to `managing focus`?
+
+ For a user totally dependent on a screen reader and/or keyboard, his interaction with our site is completely based on
+ where the current focus of the application lies.
+
+.l-sub-section
+ :marked
+ Focus is broken down into `keyboard focus`, which refers to the area of the page that will next be affected by a
+ keyboard action and `reading focus`, which refers to where the screen reader will next start reading from.
+
+:marked
+ In this section we will be looking primarily at `keyboard focus`. By correctly managing `keyboard focus`, the
+ `reading focus` will usually also be correct.
+
+.l-sub-section
+ :marked
+ For those using keyboard only navigation, focus is typically set one focusable element forward using `Tab`
+ or one element backward using `Shift+Tab`. Why not try it now? Go to your favorite online shopping site and
+ see if you can order your next product using only `Tab` and `Shift+Tab` for navigation and `Enter` to select
+ actions. Walking a mile in the shoes of someone who cannot use a mouse can give us a lot of respect for why we
+ should make our websites accessible.
+
+:marked
+ ### Outline marks the spot
+
+ We have all seen it, the blue box that web browsers draw around the currently focused `element`. This is rendered
+ through the `outline` style property.
+
+figure.image-display
+ img(src="/resources/images/cookbooks/a11y/standard-focus-outline.png" alt="Standard browser focus outline box")
+
+:marked
+ It clearly indicates where the current `keyboard focus` of the application lies. As it turns out, this is one
+ of the non-negotiables of `a11y`. We **HAVE** to visually show where the current `keyboard focus` lies.
+ Someone navigating a website with keyboard input alone cannot do so unless this is always clear.
+
+ Unfortunately, the solid blue box does not meet everyone's approval in a world filled with opacities and box-shadows.
+ This leads to one of the most infamous of unforgivable sins of `a11y`.
+
+.callout.is-important
+ header Leave the focus outline intact!
+ :marked
+ **DO NOT** under any circumstances remove the focus outline for interactive elements. **NEVER** completely
+ remove this with the style commands `outline:0` or `outline:none`, unless you intend to implement your own.
+ You will instantly make your site unusable for any sighted user who uses the keyboard or related assistive
+ technologies.
+
+:marked
+ If you really hate the default implementation, please **DO** replace this with another style that shows up when
+ the interactive element receives focus.
+
+ You could do something like this:
+
+figure.image-display
+ img(src="/resources/images/cookbooks/a11y/custom-focus-outline.png" alt="Standard browser focus outline box")
+
+:marked
+ We accomplish this with the following style by taking a cue from `Twitter Bootstrap`:
+
++makeExample('cb-a11y/ts/a11y.css', 'cb-a11y-managing-focus-custom-outline')
+
+:marked
+ Here we use the forbidden `outline:0`, **BUT** we then immediately give it another visual focus style.
+
+:marked
+ ### Focus flow
+
+ In Angular 2 we have unequaled power to create easily reusable components. Let us think for a moment
+ about the pages we put together with these components.
+
+ If you tried out any `keyboard navigation` in the previous section, you would have noticed that the `keyboard focus` simply
+ moves from one element to the next on the page. Our page layouts should support this to create a natural flow.
+
+ How much would you enjoy it if anyone forced you to scroll up and down on a page to find the next element you want to interact
+ with? Not at all much? Well, we should not force this on any user. We should design a logical flow of focus throughout every page
+ in our application.
+
+.l-sub-section
+ :marked
+ Unless modified through script, the `normal flow of focus` will jump one focusable element up or down in the order that they
+ appear in the `HTML DOM Tree`, regardless of visual page position. By ensuring that your `HTML` has a logical
+ structure, you make sure that all users can navigate your pages correctly. Where you place the elements
+ with `CSS` does not affect this order. We call this the `Separation of Content and Presentation`.
+
+:marked
+ We saw in the labeling section that we get a lot of standard `a11y` functionality out of the box when we use
+ `native form controls`, and here it is no different. **DO NOT** change the focus order with script unless
+ it is for a very specific functional reason you cannot solve with the default flow, like focusing
+ on an error message the user needs to see.
+
+ Let's have a look at a basic example of separating content from presentation. We have a basic layout based on a list
+ of countries, asking for two pieces of information per country. It looks like this:
+
+figure.image-display
+ img(src="/resources/images/cookbooks/a11y/focus-flow-clean.png" alt="Collection of inputs based on country list separated into columns per information type")
+
+.l-sub-section
+ :marked
+ Note how we repeated the country name in both related `input labels`. Had we instead chosen for `How many months did you work
+ there`, we would have made yet another common `a11y` mistake. **DO NOT** rely on visual context alone
+ when labeling `HTML elements`. A person with a visual disability cannot see this context so you need to tell them,
+ through the screen reader, what the current element relates to.
+
+:marked
+ If we create this layout in the `HTML DOM Tree`, one column below the other, we end up with the following focus flow:
+
+figure.image-display
+ img(src="/resources/images/cookbooks/a11y/focus-flow-bad.png" alt="Incorrect focus flow grouping taborder into columns")
+
+:marked
+ The example's simplicity and the choice of labeling make this usable, but the flow is illogical. Generally,
+ the user would want to think about one country at a time. This flow could force a user to
+ think about each country twice.
+
+ A far superior focus flow is:
+
+figure.image-display
+ img(src="/resources/images/cookbooks/a11y/focus-flow-good.png" alt="Correctly flowing focus by country")
+
+:marked
+ We do this by managing the focus flow through the `content` with `HTML` alone and changing the visual `presentation` with
+ `CSS`. Just like that we are able to create the required flow with absolutely no scripting!
+
+ Here is the `HTML`:
+
++makeExample('cb-a11y/ts/app/managing-focus/a11y-managing-focus.component.html', 'cb-a11y-managing-focus-flow')
+
+:marked
+ ### Skiplinks
+
+ We now know about `keyboard focus` and how it flows on the page. Let's zoom out a bit and look at the complete page.
+ For a sighted person who navigates the web using a mouse, it is very easy to skip sections of web pages.
+ This could be because they are returning to a website they know very well, or because they can immediately see and interact
+ with a specific section of interest.
+
+ Now imagine being forced to click on **EVERY** menu and **EVERY** link and **EVERY** field and... You get the picture.
+ That is as much fun as watching the grass grow! Now what if we tell you that a person navigating the web
+ with his keyboard alone often gets forced into exactly this situation?
+
+ If we force these users to repeatedly navigate through entire pages to find one area they want to interact with, it
+ adds a serious barrier.
+
+ We can give quick links to subsections of our pages that remain completely hidden until focused through
+ `keyboard navigation`. These are called `skiplinks` and they (could) look like this:
+
+figure.image-display
+ img(src="/resources/images/cookbooks/a11y/skiplinks.png" alt="Correctly flowing focus by country")
+
+:marked
+ You can, of course, give any styling you like, but here is how we made ours:
+
++makeExample('cb-a11y/ts/app/managing-focus/a11y-managing-focus.component.html','cb-a11y-managing-focus-skiplinks-links')
+
+:marked
+ These links point to internal `id's` and we build them with a function leveraging the `router`. *Please refer to the
+ section on `routing` in the documentation for a more detailed explanation.*
+
+ They are then rendered out as `internal links`:
+
+code-example(language="html" escape="html" format="linenums").
+ Go directly to focus flow
+
+:marked
+ If the target of this link is not an interactive element, we can make that element focusable by adding
+ `tabindex="-1"`. If we do not, it will not work in all browsers!
+
+.l-sub-section
+ :marked
+ When we use `tabindex="-1"` we are allowing an element to
+ accept the current `keyboard focus`. However, this tells the browser to keep the element out of the normal
+ `keyboard navigation` flow. It can only accept focus via internal links, clicks or script.
+
+:marked
+ The `HTML` of the target now looks like this:
+
++makeExample('cb-a11y/ts/app/managing-focus/a11y-managing-focus.component.html','cb-a11y-managing-focus-skiplinks-destination')
+
+:marked
+ Finally we need some styling magic to make it all work by only showing focused links:
+
++makeExample('cb-a11y/ts/a11y.css', 'cb-a11y-managing-focus-skiplinks-style')
+
+:marked
+ Quite easy, isn't it? Yet it is such an extremely powerful feature for a large group of users out there.
+
+ Up to this point of this section, we have made very little use of Angular 2. Yes folks,
+ this is standard `HTML` functionality and we need to know about if we are to make accessible Angular 2 applications!
+
+ Now that we know more about how browsers handle focus and what we can do to leverage it, it is time to look at what
+ we can do inside our custom Angular 2 components to keep them accessible.
+
+:marked
+ ### Interactive components should accept focus
+
+ Unlike native interactive `HTML` elements, `custom interactive components` created with Angular 2 need our help
+ to accept focus within the normal focus flow of the page during `keyboard navigation`.
+
+ This means that a native `button` element will accept focus, but a `button control` built as a
+ `custom element` from non interactive `HTML` elements won't. Not unless we do something about it.
+
+ So let's go a bit crazy and do exactly that, but first, another word of warning.
+
+.l-sub-section
+ :marked
+ Again we need to stress that re-creating any `native HTML element` out of `custom elements` is **NOT** recommended, nor
+ do we make any promises about the production readiness of our example. Our focus remains on `a11y` and how
+ we have the tools to make the most stubbornly inaccessible component accessible.
+
+:marked
+ *So what doth a great button make?*
+
+ A `button` should tell everyone that it is a button. And that includes people (whether they can or can't see),
+ browsers and assistive technologies like screen readers. It should look like a button, act like a buttons, and
+ click like a button.
+
+ A `button` should accept focus, react to the mouse `click` event and react to the keyboard `enter` and `space` events.
+ *There is a set of rules governing which keyboard events should ideally be implemented per widget and you can read
+ about these [Common Widget Design Patterns](https://www.w3.org/WAI/intro/accessibility.php) at the `W3C`*.
+
+ This is our mission, and we choose to accept it:
+
++makeTabs('cb-a11y/ts/app/shared/a11y-custom-button.component.ts,cb-a11y/ts/app/shared/a11y-custom-button.component.html',
+null, 'a11y-custom-button.component.ts,a11y-custom-button.component.html')
+
+:marked
+ We manipulate the `Host` element of our component and *Hey Presto*, it can now be used like the standard `button` element:
+
++makeExample('cb-a11y/ts/app/managing-focus/a11y-managing-focus.component.html','cb-a11y-custom-button-usage')
+
+:marked
+ Looking at the generated `HTML` we see:
+
+code-example(language="html" escape="html" format="linenums").
+
+ Do something...
+
+
+:marked
+ **Important**: Note the `role` and `tabindex`.
+
+ The `ARIA role` of this element is `button`. It tells any assistive technologies that this element is
+ a button, regardless of the original design of the `HTML` element. More information on this later.
+
+ Setting the `tabindex` to `0` inserts the element in the default flow of`keyboard navigation` focus. This means that our
+ element also becomes accessible via the keyboard!
+
+.l-sub-section
+ :marked
+ **DO NOT** use a `tabindex` value of `1` or greater as this will change the default keyboard navigation.
+
+:marked
+ ### Internal focus management for components
+
+.callout.is-important
+ header There be monsters here!
+ :marked
+ Let's kick of this topic with a warning. If our code changes focus in a way that the user does not expect,
+ it can **VERY EASILY**
+ break `a11y` in our application. We should set the focus programmatically very sparingly and only where
+ the default focus flow does not work. For example when opening a `modal window` we should make sure that we
+ set and contain the focus
+ in it, or when focusing the attention on an incorrect input so that the user can easily correct it. **DO NOT** use this
+ to navigate on the user's behalf. Everyone uses web pages in a personal way and enforcing **our way** on
+ our users can make our pages unusable and confusing.
+
+:marked
+ Usually, setting focus programmatically is only required in complex widgets. Often it is possible to solve
+ the problems in far less code using standard `HTML` or `ARIA` function. We would still like to show how you can
+ do it.
+
+ As this is an `a11y` cookbook and not `Dial-A-Widget`, we are going to seriously trim down on functionality and
+ get down to the nuts and bolts of what we need to do. The concepts demonstrated in this code can easily be applied
+ in any component, regardless of the complexity.
+
+ We have created a `button` that shows an `alert`, then sets focus on the `alert` and later allow the
+ user to close the error message with a `close button`. Extremely useful, we know...
+
++makeTabs('cb-a11y/ts/app/managing-focus/a11y-error-demo.component.html,cb-a11y/ts/app/managing-focus/a11y-error-demo.component.ts',
+null, 'a11y-error-demo.component.html,a11y-error-demo.component.ts')
+
+:marked
+ We are setting focus on an `alert` that starts out hidden. As `hidden` and `disabled` elements cannot accept focus,
+ we first need this element to become visible again. To give the browser time to apply this change we set our focus using
+ a `timeout` function.
+
+ Also note how we are using the `local template variable` to easily set focus right inside our template code!
+
+ We also use `ARIA` to apply the role of `alert` and manage the `aria-hidden` property. Yes, we even have something
+ in `ARIA` we can use to tell screen readers when an element is hidden or not. Pretty neat, hey?
+
+.l-sub-section
+ :marked
+ When you have to adjust the focus programatically, make sure that you test the result with a screen reader! The results
+ are often not what you expect.
+
+:marked
+ ### Section summary
+
+ In this section we saw how important `keyboard focus` is to make sure that many of our users are able to
+ navigate our web pages.
+
+ We looked at displaying the current `keyboard focus` and how to build our component templates with a
+ natural flow of focus in mind.
+
+ Finally we looked at what we can do to make sure that our own `components` can accept `focus` and how to
+ programmatically manage `focus` in our components.
+
+ Keep reading to further explore `a11y` in Angular 2 or [go back to the table of contents](#toc)
+
+.l-main-section
+
+:marked
+ ## Roles for custom component widgets
+
+ Angular 2, and its predecessor, opens up web development to a large group of developers, including those who
+ are developing web interfaces for the first time. In fact, this `Web Development Platform` makes it so easy to
+ create web applications and manipulate the `DOM` that it is often easy to forget that `Web Development` should be founded on `HTML`.
+
+ `HTML` is the only way to tell
+ the browsers what you would like them to show on-screen. Even when we manipulate the `DOM` with `script`, we are simply
+ manipulating a logical structure created from our `HTML`.
+
+ Yes, we know that many of you already know this, but it is very important to realise that without an understanding
+ of `HTML`, and how browsers go about interpreting our `markup`, it is very hard to get a good understanding
+ of `a11y`.
+
+ This is not as scary as it sounds, though. In the earlier sections we have already built up a solid understanding
+ of some key `HTML` concepts that support `a11y` and now we are about to give you the next weapon in your
+ `a11y` arsenal!
+
+:marked
+ ### Roles in HTML
+
+.l-sub-section
+ :marked
+ Throughout this cookbook, we have often looked at the benefits of using native `HTML` elements to
+ create the functionality we seek. The constant repetition is intentional and we will look at it again
+ as this remains such an important concept in building accessible web applications.
+
+:marked
+ Browsers are built to interpret our `HTML` according to the
+ [HTML 5 specification](https://www.w3.org/TR/html5/). Within this document we find each `HTML` element's definition.
+
+.l-sub-section
+ :marked
+ We assume the use of `HTML 5`. However, the `ARIA` concepts also work with `HTML 4`.
+
+:marked
+ We could say that each `HTML` element has a `Type` and that the browsers react based on this specific type
+ when encountering a specific element.
+
+ This is one way of looking at `Roles` in `HTML`. Each element plays a specific `role` on the page based on the specification.
+
+.l-sub-section
+ :marked
+ Each browser knows what to do when it encounters an `input` or a `button` and in the wonderful world of `a11y` the
+ browsers pass this information through to screen readers and other assistive technologies through another
+ information tree called the [Accessibility Tree](https://www.w3.org/WAI/PF/aria-implementation/#intro_treetypes).
+
+:marked
+ With Angular 2 we can extend or change existing elements' functions, or we can create new `Custom Elements`.
+
+ We can make a `div` act like an `input` or a `button`, or we can create a reusable widget
+ called `my-seriously-cool-widget`, which is in itself a collection of known `HTML` elements or other custom controls.
+
+ However, browsers still expect the known elements to act according to the specification,
+ whilst they have no idea what our new custom elements do. This means that the `Accessibility Tree` will not be correct,
+ and this sends users who depend on assistive technologies on a wild goose chase.
+
+ Fear not! We have all the tools we need at out fingertips to tell the browsers, and indirectly the screen readers,
+ what type of element we are creating!
+
+:marked
+ ### ARIA Roles to the rescue
+
+ Within the realms of `ARIA`, we can apply roles to elements that either tell the browser to override the
+ current `role` of a known element, or give a familiar role to a totally new custom element.
+
+ In this way we can give all the information that assistive technologies need, regardless of the `HTML` structure!
+
+.l-sub-section
+ :marked
+ It is important to note that applying an `ARIA Role` overrides the implicit role of native elements. Therefore, unless
+ you are changing the `role`, do not apply an `ARIA Role` to an element if the implicit role is correct.
+
+
+:marked
+ ### How to apply an ARIA Role in Angular 2
+
+ We give an `ARIA Role` to an element by setting the value of the `role` attribute. When we write this directly in our `HTML`
+ it is as simple as:
+
+code-example(language="html" escape="html" format="linenums").
+
I am an alert.
+
+:marked
+ That was easy! After all the discussion at the start of the chapter you would be forgiven for expecting a very complex
+ implementation. This is really all there is to it.
+
+ To see how we can use this in an Angular 2 template, we turn to an old friend from our `labeling` section:
+
++makeExample('cb-a11y/ts/app/shared/a11y-custom-control.component.html')
+
+:marked
+ We will often need to apply a role directly to the custom elements we create with our components. So
+ how do we do that?
+
+ In Angular 2 we refer to this new custom element as the `Host Element` of the component, because this is the element
+ in our `HTML` that hosts our component's implementation.
+
+ Angular 2 gives us everything we need to manipulate our `Host Element` through the `Host Property`
+ of our component definition. Again a familiar example makes a repeat appearance:
+
++makeExample('cb-a11y/ts/app/shared/a11y-custom-button.component.ts')
+
+:marked
+ You can see that we apply the `role` of `button` to the host element. We can even check and see that this is rendered into the resultant
+ `DOM` element:
+
+code-example(language="html" escape="html" format="linenums").
+
+ Do something...
+
+
+:marked
+ Now our browser, and any attached assistive technologies, suddenly know that `a11y-custom-button` is a `button`!
+
+ This is really super easy, but there is one more missing ingredient. We need to know which roles we can use, of course.
+
+ Let's look at the two main sections of `roles` we can use to make our applications accessible.
+
+.l-sub-section
+ :marked
+ There are more roles available. You can read the full documentation at the `W3C`, but these two sections of roles
+ are what we really need when looking at the `structure` and `roles` of the applications and widgets we create.
+
+:marked
+ ### ARIA Roles: The landmark roles
+
+ The first section of roles we look at is `Landmark Roles`. These refer to `navigational landmarks` or the regions of the
+ page the user may want quick access to. Screen readers are also aware of these regions and this helps to give the user
+ a clearer *picture* of the page layout.
+
+ In a way these roles are the most difficult to master as they refer to the overall page structure and require us to think about
+ the layout of components on a page to create the `landmarks`. Therefore, these roles should usually be
+ used inside our `Smart Components` as they need some knowledge of the application structure and general layout.
+
+ Visit the `W3C` to read more about the following [Landmark Roles](https://www.w3.org/TR/wai-aria/roles#landmark_roles):
+
+ - application
+ - banner
+ - complementary
+ - contentinfo
+ - form
+ - main
+ - navigation
+ - search
+
+.callout.is-important
+ header Avoid role="application"
+ :marked
+ The `application` role exists to tell assistive technologies that it is about to enter a heavily scripted web application
+ and switch into `application mode`. However, if our `HTML` follows the rules we have discussed so far, this role does more
+ harm than good. Use this sparingly and avoid altogether unless you know when to use it and why you are using it for
+ the specific application.
+
+:marked
+ `HTML 5` provides native `semantic elements` that implicitly carry many of these roles and we recommend that you use these
+ when possible.
+
+ Let's have a look at a high level `HTML` layout for a page using the `HTML 5 Semantic Elements`:
+
+code-example(language="html" escape="html" format="linenums").
+
+
+
+
+
+
+
+
+
+
+
+
+.l-sub-section
+ :marked
+ *"But you just told us not to apply the `role` attribute to elements when they already imply the `role`! What gives?"*
+ This is true, but for these landmark elements we should also give the roles as some browsers do not implement
+ the native `semantic elements` properly. Don't worry you still get enough benefit from using them.
+
+.l-sub-section
+ :marked
+ There is another piece of technology that reads our web pages almost like a screen reader. And that is the `search engine`.
+ Yes, using a proper
+ document structure with `semantic elements` also helps search engine crawlers to read and index our websites more easily.
+ Talk about winning on three fronts! `Readability`, `a11y` and `Search Engine Optimization`.
+
+:marked
+ When it is totally impossible to use these elements, like when you need to support `HTML 4`, we can still
+ create this structure in our `HTML` using `ARIA Roles`:
+
+code-example(language="html" escape="html" format="linenums").
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.l-sub-section
+ :marked
+ In the previous section we looked at `skiplinks`. The `landmarks` are great skiplink destinations. Yet another
+ benefit of using a proper `HTML` layout to structure your page. It also becomes clearer for
+ you as well.
+
+:marked
+ ### ARIA Roles: The widget roles
+
+ The other section of `ARIA Roles` we will briefly look at is `Widget Roles`. These roles are of particular
+ interest to us as Angular 2 developers, and because we often build highly functional widgets, it is important
+ to give them the appropriate role, where possible.
+
+ Visit the `W3C` to read more about these [Widget Roles](https://www.w3.org/TR/wai-aria/roles#widget_roles):
+
+ The following roles are for standalone widgets:
+ - alert
+ - alertdialog
+ - button
+ - checkbox
+ - dialog
+ - gridcell
+ - link
+ - log
+ - marquee
+ - menuitem
+ - menuitemcheckbox
+ - menuitemradio
+ - option
+ - progressbar
+ - radio
+ - scrollbar
+ - slider
+ - spinbutton
+ - status
+ - tab
+ - tabpanel
+ - textbox
+ - timer
+ - tooltip
+ - treeitem
+
+ There is also a set of roles for `composite widgets`. Those are widgets built up from other widgets.
+ - combobox
+ - grid
+ - listbox
+ - menu
+ - menubar
+ - radiogroup
+ - tablist
+ - tree
+ - treegrid
+
+ Wow, we have a role for every base type of widget! We have shown how easy it is to apply these roles to our templates
+ and components, so again we saw that writing accessible applications really does not take much extra effort once
+ the secrets of `a11y` have been demystified.
+
+.l-sub-section
+ :marked
+ The names of these widget roles are self-explanatory, so we will not dive into a further discussion. Visit the
+ `W3C` documentation, if in doubt.
+
+:marked
+ ### Section summary
+
+ In this section we looked at how we tell the browser what type of `custom widget component` we are making. We also
+ saw how we can override the role of a native `HTML` element.
+
+ We saw that Angular 2 makes applying a `role` to our `custom elements` easy by using
+ the `Host Element`.
+
+ Finally, we had a look at the most interesting `ARIA Roles` for us as Angular 2 developers.
+
+ [Go back to the table of contents](#toc)
+
diff --git a/public/resources/images/cookbooks/a11y/custom-focus-outline.png b/public/resources/images/cookbooks/a11y/custom-focus-outline.png
new file mode 100644
index 0000000000..664d2babbe
Binary files /dev/null and b/public/resources/images/cookbooks/a11y/custom-focus-outline.png differ
diff --git a/public/resources/images/cookbooks/a11y/focus-flow-bad.png b/public/resources/images/cookbooks/a11y/focus-flow-bad.png
new file mode 100644
index 0000000000..f8b5b800bc
Binary files /dev/null and b/public/resources/images/cookbooks/a11y/focus-flow-bad.png differ
diff --git a/public/resources/images/cookbooks/a11y/focus-flow-clean.png b/public/resources/images/cookbooks/a11y/focus-flow-clean.png
new file mode 100644
index 0000000000..c4f702ff0c
Binary files /dev/null and b/public/resources/images/cookbooks/a11y/focus-flow-clean.png differ
diff --git a/public/resources/images/cookbooks/a11y/focus-flow-good.png b/public/resources/images/cookbooks/a11y/focus-flow-good.png
new file mode 100644
index 0000000000..4bfa2ccbd0
Binary files /dev/null and b/public/resources/images/cookbooks/a11y/focus-flow-good.png differ
diff --git a/public/resources/images/cookbooks/a11y/invisible-label-input-labeled.png b/public/resources/images/cookbooks/a11y/invisible-label-input-labeled.png
new file mode 100644
index 0000000000..e41e4ca914
Binary files /dev/null and b/public/resources/images/cookbooks/a11y/invisible-label-input-labeled.png differ
diff --git a/public/resources/images/cookbooks/a11y/invisible-label-input-not-labeled.png b/public/resources/images/cookbooks/a11y/invisible-label-input-not-labeled.png
new file mode 100644
index 0000000000..601c7c14a9
Binary files /dev/null and b/public/resources/images/cookbooks/a11y/invisible-label-input-not-labeled.png differ
diff --git a/public/resources/images/cookbooks/a11y/skiplinks.png b/public/resources/images/cookbooks/a11y/skiplinks.png
new file mode 100644
index 0000000000..6b07bd4bdf
Binary files /dev/null and b/public/resources/images/cookbooks/a11y/skiplinks.png differ
diff --git a/public/resources/images/cookbooks/a11y/standard-focus-outline.png b/public/resources/images/cookbooks/a11y/standard-focus-outline.png
new file mode 100644
index 0000000000..ee72ad0f46
Binary files /dev/null and b/public/resources/images/cookbooks/a11y/standard-focus-outline.png differ