23 November 2010
Intermediate
Not all users experience web content in the same manner. In Flash (SWF) content, you can implement tab navigation to make websites usable without a mouse. You can also implement accessibility aids to make Flash content usable for people with physical disabilities. A screen reader, for example, can be used to present graphics and text as speech to aid the visually impaired. This article covers basic tasks you will encounter when creating accessible Flash content.
It's a good idea to make every interactive element in your application accessible using the keyboard. By pressing the Tab key, a user can easily shift between interactive elements on a web page without having to use the mouse. This is particularly useful for forms-based web content.
When a user has focus within a SWF file, the Tab key will automatically cycle through all interactive objects. This includes text fields, buttons, and user interface components. Sprites or movie clips do not acquire focus when the user presses the Tab key. You can add these objects to the tab order sequence by setting the object's tabEnabled property to true. The following example creates a grid of squares that change color when acquiring and losing focus:
var rows:uint = 5;
var cols:uint = 5;
for(var i:uint = 0; i < rows; i++) {
for(var j:uint = 0; j < cols; j++) {
var s:Sprite = new Sprite();
// Start filling with red
s.graphics.beginFill(0xFF0000);
// Draw a box
s.graphics.drawRect(0,0,20,20);
s.graphics.endFill();
s.x = 10 + (j * 30);
s.y = 10 + (i * 30);
// Run the changeToBlue function every time the user changes focus to this sprite
s.addEventListener(FocusEvent.FOCUS_IN, changeToBlue);
// Run the changeToGreen function every time the user changes focus away from this sprite
s.addEventListener(FocusEvent.FOCUS_OUT, changeToGreen);
// Enable this sprite in the tab sequence
s.tabEnabled = true;
addChild(s);
}
}
function changeToBlue(e:FocusEvent):void {
var s:Sprite = e.target as Sprite;
s.graphics.clear();
s.graphics.beginFill(0x0000FF)
s.graphics.drawRect(0,0,20,20);
s.graphics.endFill();
}
function changeToGreen(e:FocusEvent):void {
var s:Sprite = e.target as Sprite;
s.graphics.clear();
s.graphics.beginFill(0x00FF00)
s.graphics.drawRect(0,0,20,20);
s.graphics.endFill();
}
To test this example, click first on one of the squares to set the focus. Then use the Tab key to change the focus from one square to another.
Note: Since Flash Professional also uses tab functionality in the authoring environment, select the Control > Disable Keyboard Shortcuts menu option in the test window. Otherwise, Flash Professional interprets the tabs instead of the test application. Or else test the published SWF file in a browser.
To get the source files for this example, download TabSprites.zip at the top of this page.
Flash user interface components are automatically included in the tab sequence. This is also true for dynamically created components. Note that the default tab order is unrelated to their position on the screen; tab sequence is built in the order that objects are created.
You can manually specify a display object's position in the tab sequence by setting its tabIndex property. Unlike display object depths, tab order is a one-based system; an item with tabIndex of 1 is the first in the sequence.
The following example creates two TextInput components and a Button component to create a form that allows a user to submit a username and password. The Submit button is created before the password field, but after the username field. Specifying the tab position ensures that the user can tab from the username field to password field to Submit button in the appropriate sequence.
Note: Since Flash Professional also uses tab functionality in the authoring environment, select the Control > Disable Keyboard Shortcuts menu option in the test window. Otherwise, Flash Professional interprets the tabs instead of the test application. Or else test the published SWF file in a browser.
import fl.controls.TextInput;
import fl.controls.Button;
var usernameField:TextInput = new TextInput();
usernameField.move(10,10);
usernameField.width = 200;
addChild(usernameField)
var submitButton:Button = new Button();
submitButton.label = "Submit";
submitButton.move(10,80);
addChild(submitButton);
var passwordField:TextInput = new TextInput();
passwordField.move(10,40);
passwordField.width = 200;
passwordField.displayAsPassword = true;
addChild(passwordField);
// Since we have created the form items in a different order than
// users expect for tabbing, manually set the tab index.
usernameField.tabIndex = 1;
passwordField.tabIndex = 2;
submitButton.tabIndex = 3;
usernameField.setFocus();
To get the source files for this example, download TabComponents.zip at the top of this page.
When Flash Player opens a SWF file in Internet Explorer, it automatically seeks the presence of a screen reader. If a screen reader is active, the SWF file provides information to the screen reader.
Note: Screen reader capability is supported only by the Flash Player ActiveX control for Internet Explorer.
Use the following code to test the following code to confirm that the Flash Player is capable of using a screen reader, and if a screen reader is detected. Clicking the text field causes the screen reader to interpret the description specified in the text field's AccessibilityProperties object:
var tf:TextField = new TextField();
tf.autoSize = TextFieldAutoSize.LEFT;
addChild(tf);
setTimeout(setAccessibility, 1000);
function setAccessibility():void {
tf.appendText("Has screen reader capability? " + Capabilities.hasAccessibility + "\n");
tf.appendText("Screen reader is active? " + Accessibility.active + "\n");
}
Opening this SWF in Internet Explorer when a screen reader is active shows true for both statements.
A screen reader can interpret the accessibility properties of the stage itself, as well as objects on the stage such as container objects, buttons, and text. You can control how the contents of your SWF are used by accessibility aids by specifying a custom AccessibilityProperties object to a display object. The name and description properties of this object are interpreted by the screen reader.
If a particular object on the screen does not need to be interpreted, you can use the silent property of the AccessibilityProperties class. For example, if it is unnecessary for a screen reader to interpret a text field, you can create a new instance of AccessibilityProperties, set that instance's silent property to true, and assign this instance to the accessibilityProperties property of your text field.
The following example creates three squares with accessibility names and descriptions that are interpreted by a screen reader if a screen reader is active. The blue box will not be interpreted since the silent property of its accessibility properties is set to true:
var redBox:Sprite = new Sprite();
redBox.accessibilityProperties = new AccessibilityProperties();
redBox.accessibilityProperties.name = "Red Box";
redBox.accessibilityProperties.description = "This is the red box."
redBox.graphics.beginFill(0xFF0000);
redBox.graphics.drawRect(0,0,40,40);
redBox.graphics.endFill();
redBox.x = 0;
redBox.buttonMode = true;
addChild(redBox);
var greenBox:Sprite = new Sprite();
greenBox.accessibilityProperties = new AccessibilityProperties();
greenBox.accessibilityProperties.name = "Green Box";
greenBox.accessibilityProperties.description = "This is the green box."
greenBox.graphics.beginFill(0x00FF00);
greenBox.graphics.drawRect(0,0,40,40);
greenBox.graphics.endFill();
greenBox.x = 50;
greenBox.buttonMode = true;
addChild(greenBox);
var blueBox:Sprite = new Sprite();
blueBox.accessibilityProperties = new AccessibilityProperties();
blueBox.accessibilityProperties.silent = true
blueBox.accessibilityProperties.name = "Blue Box";
blueBox.accessibilityProperties.description = "This is the blue box."
blueBox.graphics.beginFill(0x0000FF);
blueBox.graphics.drawRect(0,0,40,40);
blueBox.graphics.endFill();
blueBox.x = 100;
blueBox.buttonMode = true;
addChild(blueBox);
By default, the forceSimple property of an AccessibilityProperties object is false. This means that all children of a display object with those accessibility properties will also be interpreted if they are eligible display objects or objects that have accessibility properties themselves. If you want to limit a screen reader to interpret only the parent display object and none of its children, you can set the forceSimple property to true.
The following example sets accessibility properties to two existing display objects: parentBox and childBox (which is nested within parentBox). The accessibility properties of childBox will not be interpreted by the screen reader:
var parentProps:AccessibilityProperties = new AccessibilityProperties();
parentProps.name = "Parent Box";
parentProps.description = "This is the parent box.";
// Set forceSimple to true, so that children of the parent
// object are not interpreted by a screen reader
parentProps.forceSimple = true;
var childProps:AccessibilityProperties = new AccessibilityProperties();
childProps.name = "Child Box";
childProps.description = "This is the child box.";
parentBox.accessibilityProperties = parentProps;
parentBox.getChildByName("childBox").accessibilityProperties = childProps;
Related Flash Quick Starts