Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

Commit e4ff008

Browse files
committed
docs(cb-a11y): Managing focus: content
1 parent cced3c0 commit e4ff008

12 files changed

+243
-25
lines changed

public/docs/_examples/cb-a11y/ts/a11y.css

+52
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,44 @@ hr {
77
border-top: 3px double #8c8b8b;
88
}
99

10+
h3 {
11+
outline: 0;
12+
}
13+
1014
.background-contrast {
1115
background-color: #0143A3;
1216
color: #fff;
1317
}
1418

19+
.skiplink a{
20+
min-height: 20px;
21+
position: absolute;
22+
width: 1px;
23+
height: 1px;
24+
padding: 0;
25+
margin: -1px;
26+
overflow: hidden;
27+
clip: rect(0, 0, 0, 0);
28+
border: 0;
29+
}
30+
31+
.skiplink a:active,
32+
.skiplink a:focus {
33+
position: static;
34+
width: auto;
35+
height: auto;
36+
margin: 0;
37+
overflow: visible;
38+
clip: auto;
39+
}
40+
41+
.custom-outline:focus {
42+
border-color: #7F0037;
43+
outline: 0;
44+
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(127, 0, 55, .6);
45+
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(127, 0, 55, .6);
46+
}
47+
1548
/* #docregion cb-a11y-form-controls-visually-hidden-style*/
1649
.visually-hidden {
1750
border: 0;
@@ -24,3 +57,22 @@ hr {
2457
width: 1px;
2558
}
2659
/* #enddocregion */
60+
61+
.like-bootstrap {
62+
display: block;
63+
width: 100%;
64+
height: 34px;
65+
padding: 6px 12px;
66+
font-size: 14px;
67+
line-height: 1.42857143;
68+
color: #555;
69+
background-color: #fff;
70+
background-image: none;
71+
border: 1px solid #ccc;
72+
border-radius: 4px;
73+
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
74+
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
75+
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
76+
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
77+
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
78+
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
<nav role="navigation">
2-
<ol>
3-
<li>
4-
<a [routerLink]="['FormControls']"><h2>Accessible form control labels</h2></a>
5-
</li>
6-
</ol>
2+
<ol>
3+
<li>
4+
<a [routerLink]="['FormControls']"><h2>Accessible form control labels</h2></a>
5+
</li>
6+
<li>
7+
<a [routerLink]="['ManagingFocus']"><h2>Managing focus</h2></a>
8+
</li>
9+
</ol>
710
</nav>

public/docs/_examples/cb-a11y/ts/app/app.component.html

+1-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,4 @@ <h1 id="top">Angular 2 A11y Cookbook</h1>
33
</header>
44
<main role="main" class="container">
55
<router-outlet></router-outlet>
6-
<!--<a11y-index></a11y-index>-->
7-
<!--<a11y-form-controls></a11y-form-controls>-->
8-
</main>
6+
</main>

public/docs/_examples/cb-a11y/ts/app/app.component.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {ROUTER_DIRECTIVES, RouteConfig, ROUTER_PROVIDERS} from "angular2/router"
33
import {A11yFormControls} from "./form-controls/a11y-form-controls.component";
44
import {A11yIndex} from "./a11y-index.component";
55
import {A11yHelper} from "./services/a11y-helper.service";
6+
import {A11yManagingFocus} from "./managing-focus/a11y-managing-focus.component";
67

78
@Component({
89
selector: 'app',
@@ -19,8 +20,9 @@ import {A11yHelper} from "./services/a11y-helper.service";
1920
})
2021
@RouteConfig([
2122
{path:'/', name: 'Index', component: A11yIndex},
22-
{path:'/formcontrols', name: 'FormControls', component: A11yFormControls}
23+
{path:'/form-controls', name: 'FormControls', component: A11yFormControls},
24+
{path:'/managing-focus', name: 'ManagingFocus', component: A11yManagingFocus}
2325
])
24-
export class AppComponent {
25-
26+
export class AppComponent {
27+
2628
}

public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-form-controls.component.html

+11-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
1+
<nav role="navigation" class="skiplink">
2+
<a [href]="generateSkiplink('#implicit')" >Implicit labelling</a>
3+
<a [href]="generateSkiplink('#explicit')">Explicit labelling</a>
4+
<a [href]="generateSkiplink('#hiding')" >Hiding labels</a>
5+
<a [href]="generateSkiplink('#custom')" >Labelling custom controls</a>
6+
</nav>
7+
18
<article role="article">
29
<header class="row well">
310
<h2>Accessible form control labels</h2>
411
</header>
512

613
<section class="row well">
714
<header>
8-
<h3>Implicit labeling</h3>
15+
<h3 id="implicit" tabindex="-1">Implicit labeling</h3>
916
<hr>
1017
</header>
1118

@@ -91,7 +98,7 @@ <h3>Implicit labeling</h3>
9198

9299
<section class="row well">
93100
<header>
94-
<h3>Explicit labeling</h3>
101+
<h3 id="explicit" tabindex="-1">Explicit labeling</h3>
95102
<hr>
96103
</header>
97104

@@ -112,7 +119,7 @@ <h3>Explicit labeling</h3>
112119

113120
<section class="row well">
114121
<header>
115-
<h3>Hiding labels</h3>
122+
<h3 id="hiding" tabindex="-1">Hiding labels</h3>
116123
<hr>
117124
</header>
118125

@@ -145,7 +152,7 @@ <h3>Hiding labels</h3>
145152

146153
<section class="row well">
147154
<header>
148-
<h3>Labeling custom controls</h3>
155+
<h3 id="custom" tabindex="-1">Labeling custom controls</h3>
149156
<hr>
150157
</header>
151158

public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-form-controls.component.ts

+4
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ export class A11yFormControls implements OnInit {
4141
constructor(private _a11yHelper:A11yHelper) {
4242
}
4343

44+
generateSkiplink(hash:string){
45+
return this._a11yHelper.getInternalLink(hash, 'FormControls');
46+
}
47+
4448
isChecked(item:string):boolean {
4549
return this._a11yHelper.isStringInArray(this.checkboxModel, item);
4650
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<div role="button"
2+
tabindex="0"
3+
(click)="onKeyDown()"
4+
(keydown.space)="onKeyDown()"
5+
(keydown.enter)="onKeyDown()"
6+
class="btn btn-primary">
7+
<ng-content></ng-content>
8+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import {Component, EventEmitter, Output} from "angular2/core";
2+
3+
@Component({
4+
selector: 'a11y-custom-button',
5+
templateUrl: './app/managing-focus/a11y-custom-button.component.html'
6+
})
7+
export class A11yCustomButton {
8+
9+
@Output()
10+
onClick: EventEmitter<any> = new EventEmitter();
11+
12+
onKeyDown(){
13+
this.onClick.emit(null);
14+
}
15+
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<nav role="navigation" class="skiplink">
2+
<a [href]="generateSkiplink('#focusoutline')" >The focus outline</a>
3+
<a [href]="generateSkiplink('#customcontrolfocus')">Focusing custom controls</a>
4+
</nav>
5+
6+
<article role="article">
7+
<header class="row well">
8+
<h2>Managing focus</h2>
9+
</header>
10+
11+
<section class="row well">
12+
<header>
13+
<h3 id="focusoutline" tabindex="-1">The focus outline</h3>
14+
<hr>
15+
</header>
16+
17+
<div class="form-group">
18+
<label>Focus me for standard browser outline:
19+
<input class="like-bootstrap">
20+
</label>
21+
</div>
22+
23+
<div class="form-group">
24+
<label>Focus me for a new and unusual outline:
25+
<input class="form-control custom-outline">
26+
</label>
27+
</div>
28+
29+
</section>
30+
31+
<section class="row well">
32+
<header>
33+
<h3 id="customcontrolfocus" tabindex="-1">Focusing custom controls</h3>
34+
<hr>
35+
</header>
36+
<a11y-custom-button (onClick)="activate()">Query</a11y-custom-button>
37+
</section>
38+
39+
</article>
40+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import {Component} from "angular2/core";
2+
import {A11yCustomButton} from "./a11y-custom-button.component";
3+
import {A11yHelper} from "../services/a11y-helper.service";
4+
5+
@Component({
6+
selector: 'a11y-managing-focus',
7+
templateUrl: './app/managing-focus/a11y-managing-focus.component.html',
8+
directives: [A11yCustomButton]
9+
})
10+
export class A11yManagingFocus {
11+
12+
constructor(private _a11yHelper:A11yHelper) {
13+
}
14+
15+
generateSkiplink(hash:string) {
16+
return this._a11yHelper.getInternalLink(hash, 'ManagingFocus');
17+
}
18+
19+
activate():void {
20+
console.log('click');
21+
}
22+
}

public/docs/_examples/cb-a11y/ts/app/services/a11y-helper.service.ts

+10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
import {Injectable} from "angular2/core";
2+
import {Router} from "angular2/router";
23

34
@Injectable()
45
export class A11yHelper {
6+
7+
constructor(private _router: Router){}
8+
9+
getInternalLink(hash: string, instructionName: string): string{
10+
let instruction = this._router.generate([instructionName]);
11+
let path = '/' + instruction.toUrlPath() + hash;
12+
return path;
13+
}
14+
515
generateUniqueIdString():string {
616
return (this.randomGuidSnippet() +
717
this.randomGuidSnippet() + "-" +

public/docs/ts/latest/cookbook/a11y.jade

+66-10
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,12 @@ include ../_util-fns
108108
## Table of contents
109109

110110
[Accessible form control labels](#form-control-labels)
111-
111+
112+
[Managing focus](#managing-focus)
113+
112114
[Using keyboard shortcuts](#keyboard-shortcuts)
113115

114-
[Component that knows its own role](#component-roles)
115-
116-
[Managing focus](#managing-focus)
116+
[Component should know its own role](#component-roles)
117117

118118
.l-sub-section
119119
:marked
@@ -446,7 +446,68 @@ null, 'a11y-input-wrapper.component.html,a11y-input-wrapper.component.ts, a11y-i
446446
Angular&nbsp;2 with the `a11y` implementations of native `HTML` elements.
447447

448448
Keep reading for more on `a11y` in Angular&nbsp;2 or [go back to the table of contents](#toc)
449+
450+
.l-main-section
451+
<a id="managing-focus"></a>
452+
:marked
453+
## Managing focus
454+
455+
Often when developers think of `a11y`, it is thought of as only being for people with visual disabilities and
456+
screen readers.
457+
458+
While we are indeed doing a lot to ensure that screen readers can properly consume and read our pages, `a11y` is
459+
about much, much more. Visual disabilites make up only a group of the disabilities that hamper access to the `web`.
460+
There is a vast group of people out there who find it difficult to use our websites because of `motor disabilities`.
461+
462+
We need to spare a thought for those out there who would love to use our shiny new Angular&nbsp;2 application, but
463+
simply cannot use a mouse. Here we are also talking about people with limited to no use of their hands. This could be
464+
for a variety
465+
of reasons, ranging from those with no hands to those who have lost the use of their hands for a period of time due to injury.
466+
This vast group of people also rely strongly on the keyboard or other types of assistive technologies for web
467+
navigation.
468+
469+
.l-sub-section
470+
:marked
471+
One of the most important aspects of `a11y` is called `keyboard accessibility`. This means that the entire website
472+
**MUST** be navigable and operable through the keyboard alone.
473+
474+
:marked
475+
So how does `keyboard accessibility` relate to `managing focus`?
476+
477+
For a user totally dependent on a screen reader or keyboard, his interaction with our site is solidly built upon
478+
where the current focus of the application lies.
449479

480+
.l-sub-section
481+
:marked
482+
Focus can be broken down into `keyboard focus`, which refers to which area of the page will next be impacted by a
483+
keyboard action and `reading focus`, which refers to where the screen reader will next start reading from. They can
484+
be the same location but it does not have to be.
485+
486+
:marked
487+
In this section we will be looking primarily at `keyboard focus`.
488+
489+
:marked
490+
### Outline marks the spot
491+
492+
We have all seen it, the blue box that web browsers draw around the next `input` we are about to type into.
493+
This is done by the `outline` style.
494+
495+
It clearly indicates where the current `keyboard focus` of the application lies. And, as it turns out, this is one
496+
of the non-negotiables of `a11y`. We **HAVE** to visually indicate the current `keyboard focus` when focus lies on
497+
and interactive `HTML` element or custom component. Someone navigating a website with keyboard input alone cannot do
498+
so unless it is always clear where the `keyboard focus` lies.
499+
500+
Unfortunately the solid blue box has not met with everyone's approval in a world filled with opacities and box-shadows.
501+
Which has lead to one of the often made unforgivable sins of `a11y`.
502+
503+
.callout.is-important
504+
header Leave the focus outline intact!
505+
:marked
506+
Do not under any circumstances remove the focus outline for interactive elements with keyboard focus. Keep it unchanged
507+
or replace with your own but **NEVER** fully remove this with the style command `outline:0`. You will instantly
508+
render your site unusable for any sighted user who has to use the keyboard or related assistive technologies.
509+
510+
450511
.l-main-section
451512
<a id="keyboard-shortcuts"></a>
452513
:marked
@@ -457,13 +518,8 @@ null, 'a11y-input-wrapper.component.html,a11y-input-wrapper.component.ts, a11y-i
457518
.l-main-section
458519
<a id="component-roles"></a>
459520
:marked
460-
## Component that knows its own role
521+
## Component should know its own role
461522

462523
Content coming soon...
463524

464-
.l-main-section
465-
<a id="managing-focus"></a>
466-
:marked
467-
## Managing focus
468525

469-
Content coming soon...

0 commit comments

Comments
 (0)