Hack 47 Use Accessibility Text as Help Text

figs/moderate.gif figs/hack47.gif

Accessibility text is normally used for screen readers for the sight impaired. However, you can also use it as help text for the sighted.

One of the big design issues that Flash MX addressed was making Flash content as accessible as other web content. The Accessibility panel was added to allow designers to define text strings that would be picked up by screen readers for the sight impaired. Flash MX 2004 carries this mission forward by building accessibility features, including better focus support, into the v2 components.

Of course, even the fully sighted sometimes want a little more help, and it may be useful to display the accessibility text to everyone, only in different forms. Here we use accessibility text as pop-up tool tips.

Adding Accessibility Properties

To add accessibility properties to a movie clip, button, or nonstatic text field (i.e., any graphical object), select the element on stage and add the appropriate information via the Accessibility panel. Figure 6-20 depicts adding accessibility text to the buttons in [Hack #96] .

Figure 6-20. Adding accessibility properties in the Accessibility panel
figs/flhk_0620.gif


If you test the movie, exported for Flash Player 6r65 or higher, you will find that the selected object has gained an _accProps property, as shown in Figure 6-21.

Figure 6-21. The _accProps property for buttonA
figs/flhk_0621.gif


The Name, Description, and Shortcut fields of the Accessibility panel appear in the name, description, and shortcut subproperties of _accProps.

You can, of course, add _accProps to an element through ActionScript. This can be useful if you are, for example, attaching your content dynamically to the timeline or have included your accessibility text as a separate file that needs parsing at runtime. The following code adds an accessibility text description field to buttonA:

buttonA._accProps.description = "some text";

Knowing this, we can easily repurpose the accessibility properties for pretty much anything we want, including:

  • Making Flash speak the accessibility text [Hack #52] for devices that have sound but are unlikely to have a screen reader, or when space is at a premium and you would rather provide verbal feedback than text on the screen.

  • Displaying the accessibility text in a help text label.

In this hack we tackle the second task. When the user rolls over a button, we use the _accProps properties to create help text for sighted people, as shown in Figure 6-22.

Figure 6-22. Pop-up help text
figs/flhk_0622.gif


Using the code for keyboard shortcuts developed in [Hack #96], we need to add three new functions that:

  • Set up the events to drive the help text. We will use the onRollOver and onRollOut events.

  • Add help text boxes to the Stage.

  • Remove the help text box when it is no longer needed.

First though, we need to create the help text either by creating the text field dynamically or by creating a new symbol that is attached to the Stage dynamically. I have chosen the second approach, and Figure 6-23 shows the movie clip symbol, helpText, containing a multiline dynamic text field with instance name helpText.

Figure 6-23. The helpText symbol
figs/flhk_0623.gif


Give the text field a border and set it to 14-point _sans text.

The code to create a simple help text box derived from the _accProps properties is shown in the next section.

The function addHelp( ) sets up the onRollOver event to call function createHelpText( ) after 1.2 seconds and clears this timer and any currently showing help text (via the onRollOut/onDragOut events) if the user moves away from the symbol.

The function createHelpText( ) attaches a new instance of the helpText movie clip symbol, populating it with _accProps information. Here are some things to note about this code:

  • The function needs to know how big the helpText text field needs to be to contain the help text. It does this by setting up a TextFormat object that mirrors the text-formatting properties of our text field and uses TexFormat.getTextExtent( ) to find out the sizing information. Unfortunately, the getTextExtent( ) method returns sizing information that is usually too small, so to overcome this, I have specified a helpFormat.size value (font size) that is slightly larger than the actual font size used in the text field.

  • We have to set the text field's background and backgroundColor properties via ActionScript, because there are no controls on the Properties panel to do this manually.

The Code

This code hijacks the accessibility text and uses it as help text. The code assumes there are three buttons with instance names buttonA, buttonB, and buttonC. The associated event handlers run when the user clicks on a button or presses the associated keyboard combo. The combos are:


Button A

A


Button B

Control+B


Button C

Control+D

Note that the word "Control" must be spelled out in the Shortcut field despite this book's convention of using "Ctrl" as shorthand for the Control key. Additionally, each button should have accessibility properties defined. To do this, open the Accessibility panel (WindowOther PanelsAccessibility) and enter a name and shortcut for each button, as shown in Figure 6-24. In this example, we use only the Name and Shortcut fields, but you can modify the code later to also show the Description field.

Figure 6-24. Adding accessibility properties to the buttons
figs/flhk_0624.gif


The following code uses the accessibility properties defined per button to create our help text and the keyboard shortcut functionality. Comments are sprinkled throughout to explain it further.

function addHelp(target) {

  target.onRollOver = function( ) {

    // Delay the appearance of the help text by 1.2 seconds

    helpInterval = setInterval(createHelpText, 1200, target);

  };

  target.onRollOut = target.onDragOut=function ( ) {

    // Hide the help text when the user rolls off the clip

    clearInterval(helpInterval);

    removeHelpText( );

  };

}

function createHelpText(target) {

  // Create a clip to hold the help text

  var helpClip:MovieClip = attachMovie("helpText", "helpText", 

                          this.getNextHighestDepth( ));

  clearInterval(helpInterval);

  // Set the attributes of the help text

  var helpText:TextField = helpClip.helpText;

  helpText.background = true;

  helpText.backgroundColor = 0xFFFFCC;

  // Format the help text

  var helpFormat:TextFormat = new TextFormat( );

  helpFormat.leftMargin = 2;

  helpFormat.rightMargin = 2;

  helpFormat.indent = 0;

  helpFormat.size = 15;

  helpFormat.font = "_sans";

  // If the target has an accessibility name, 

  // display it in the help text box.

  if (target._accProps.name != undefined) {

    helpText.text = target._accProps.name;

  }

  if (target._accProps.shortcut != undefined) {

    // If the target has a keyboard shortcut, 

    // add it to the help text box.

    helpText.text += "\n" + target._accProps.shortcut;

  }

  // Set the help text's dimensions

  var fieldSize:Object = helpFormat.getTextExtent(helpText.text);

  helpText._height = fieldSize.textFieldHeight;

  helpText._width = fieldSize.textFieldWidth;

  helpClip._x = _xmouse - helpClip._width / 2;

  helpClip._y = _ymouse - helpClip._height - 10;

}

function removeHelpText( ) {

  helpText.removeMovieClip( );

}

function aHandler( ) {

  // Event handler for button A

  trace("You clicked A");

}

function bHandler( ) {

  // Event handler for button B

  trace("You clicked B");

}

function cHandler( ) {

  // Event handler for button C

  trace("You clicked C");

}

function down( ) {

  // Function to detect a key combo and 

  // run the associated button script.

  var allKeys;

  // Test to see if all the keys in the combo are down

  for (var j = 0; j < keys.length; j++) {

    allKeys = true;

    for (var i = 0; i < keys[j].combo.length; i++) {

      allKeys = allKeys && Key.isDown(keys[j].combo[i]);

    }

    if (allKeys) {

      // If all the keys in the combo are down, give the 

      // associated button focus, and run the associated

      // button's event handler. Finally, disable further 

      // events until the combo is released.

      Selection.setFocus(keys[j]);

      this.onKeyDown = undefined;

      this.onKeyUp = up;

      keys[j].btn.onRelease( );

      break;

    }

  }

}

function up( ) {

  // Function runs when a combo is released

  this.onKeyUp = undefined;

  this.onKeyDown = down;

}

//

var keys:Array = new Array( );

var keyListener:Object = new Object( );

keys[0] = {btn:buttonA, combo:[65]};

keys[1] = {btn:buttonB, combo:[Key.CONTROL, 66]};

keys[2] = {btn:buttonC, combo:[Key.CONTROL, 68]};

buttonA.onRelease = aHandler;

buttonB.onRelease = bHandler;

buttonC.onRelease = cHandler;

addHelp(buttonA);

addHelp(buttonB);

addHelp(buttonC);

keyListener.onKeyDown = down;

Key.addListener(keyListener);

Figure 6-25 shows an example of the code running. In this example, Button B has an accessibility name of "Button B," and the Shortcut field is Control+B; rolling over the button reveals this information. If the user presses Control+B, the button event handler bHandler( ) runs.

Figure 6-25. The help text for Button B
figs/flhk_0625.gif


Note that the code doesn't check whether the help text is outside the Stage area, nor does it ensure that the text isn't obscured by the cursor (at the current mouse position). The preceding code shows the basic idea, and you can add other features fairly easily.

Final Thoughts

By developing this hack and adding keyboard shortcuts [Hack #96], you have a site that is not only more accessible to users who use screen readers but also a site that uses the same help information for the sighted. This allows you to free up screen real estate by placing information in your accessibility text, safe in the knowledge that everyone will see it, making for a cleaner and more pleasing overall design.