« New list of State Policies | Main | Flash Reading Order Cases »
May 08, 2003
Reading Order in Flash
One of the most common accessibility issues in Flash is a poor reading order. Flash uses an equation to (roughly) approximate the reading order. The equation is
![]()
where x and y are the distance from the top left hand corner of the stage to the top left hand corner of the instance of the object. This equation roughly maps out the stage in straight lines, from left to right, top to bottom. However, it suffers from an odd little quirk. As you near the end of the first line, it jumps back and forth between the first and second lines.
My friend and colleague Andrew Kirkpatrick from NCAM created a clever little movie to illustrate this. In this movie, I see three rows of letters appearing alphabetical order. I would expect them to read in alphabetical order as well.
Try tabbing between the letters in this wacky letter example. Since the reading and tab order in Flash are synonymous, the tab order serves as a good approximation of the reading order.
To control this issue, we simply need to add a list of .tabindex values to the movie. This is not a complex task, but it carries an important caveat (there are other caveats, but we’ll save them for another day). In order to control the reading order, you must specify the tab index for the every instance in the movie, not just a few instances. Miss one instance and the entire order returns to the default reading order.
I dutifully add instance names for every instance in my movie. Next, I add the code for the tab index.
_root.a_mc.tabindex = 1;
_root.b_mc.tabindex = 2;
_root.c_mc.tabindex = 3;
_root.d_mc.tabindex = 4;
_root.e_mc.tabindex = 5;
_root.f_mc.tabindex = 6;
_root.g_mc.tabindex = 7;
_root.h_mc.tabindex = 8;
_root.i_mc.tabindex = 9;
_root.j_mc.tabindex = 10;
_root.k_mc.tabindex = 11;
_root.l_mc.tabindex = 12;
_root.m_mc.tabindex = 13;
_root.n_mc.tabindex = 14;
_root.o_mc.tabindex = 15;
_root.p_mc.tabindex = 16;
_root.q_mc.tabindex = 17;
_root.r_mc.tabindex = 18;
_root.s_mc.tabindex = 19;
_root.t_mc.tabindex = 20;
_root.u_mc.tabindex = 21;
_root.v_mc.tabindex = 22;
_root.w_mc.tabindex = 23;
_root.x_mc.tabindex = 24;
_root.y_mc.tabindex = 25;
_root.z_mc.tabindex = 26;
Now if I tab through the finished example, I will see that the tab order is just as I would have expected based on what I see visually.
Posted by Bob Regan at May 8, 2003 10:05 PM
Comments
Hi Bob,
This is a good solution but it looks to me that it's not that feasibile when dealing with dynamic content in a Flash movie. Defining the tabbing order before hand assums that nothing in the movie is going to change but as we know, this is not the case with a lot of flash content which constantaly changes according to remote data feeds and user interaction for example. There is no way at the moment, as far as I can tell, to introduce the new objects into the tabbing cycle which makes this solution limited to static movies.
A possible solution will be some sort of a tabbing accessibility component which will introduce the new objects into the cycle in some way. It will manage the array of the tabindex and assign it to each object and new object that is introduced in the movie during runtime.
Such a component, like the accessibility component I have developed, will have to identify any new object in the movie which gets a bit tricky when dealing with the loadMovie, attachMovie and createEmptyMovieClip methods. Another solution would be to treat the objects which are assinged with a tabindex as containers and not the data itself. However, this solution will have an effect on the course of development and design of the movie, which is something we try to avoid when aiming to support accessibility. I think a better example than a page with single ABC movieclip would be something like the the RIA Macromedia is hailing or at least a dynamic site since these are the products developers are faced with makiing accessible, not a 26 movieclips demo movie.
Posted by: Amir Dotan at May 9, 2003 02:45 AM
HI Amir.
This example, introduces the concept but as the content gets more complex, so too do the strageies.
I will endeavor to build examples illustrating the variety of techniques I have come across.
The next step from here is, exactly as you described, to treat the Flash objects as containters, not content. As new content loads, the tabindex is already in place.
This presumes you know how many instances are on the stage at any time. If this is not the case, you need another method altogether. The most clever I have seen detects a screen reader. If one is present it generates a background movie clip that loads all of the same content in a single, very narrow column. The foreground elements are hidden (.silent = true). The end result is a screen that looks the same but reads perfectly.
Cheers,
Bob
Posted by: Bob Regan at May 9, 2003 06:31 AM
wow :) that sounds niceee.... I think that container-oriented thinking will be a good approach in trying to ensure accessibility across dynamic content. My only concern is that it might deter some developers since it requires them to change the way they are used to do things. It is probably a better practice anyway but I think that supporting accessibility should be as seamless as possible and not be regarded as a time/cost consuming obligation. The innovative solution you descried sounds like some sort of "text only version" a la Flash where you get a linear content-only display. Might be a direction worth looking into.
Posted by: Amir Dotan at May 9, 2003 02:53 PM
What about nested movieclip objects? as we all know, nesting movieclip is a rudimentary concept in Flash development and is used extensively in projects. I've tried to tab through a nested movieclip:
clip1.tabIndex = 1;
clip1.ball.tabIndex = 2;
clip2.tabIndex = 3;
clip3.tabIndex = 4;
but the tabbing skipped the nested movieclip and affected only the three movieclips on the main root. Any way to resolve this? or is tabbing limited to the root level only?
Posted by: Amir Dotan at May 10, 2003 02:45 PM
Hi Amir,
Today's post might help. I dusted off some notes of mine from a while back about tab order.
I would need to see your original file to know exactly what the problem is. If you think to keep in mind:
1. Make sure every instance has been assigned instance name.
2. Make sure the tab index lists the last child in every parent - child relationship.
3. See case nine in today's post.
Let me know if you any more troubles.
Cheers,
Posted by: Bob Regan at May 11, 2003 10:28 PM
Hi BoB,
today i noticed that the tabIndex will not work if I use _level for the flash movie.
For example: _level1.buttonName_btn.tabIndex=3;
Posted by: KS at August 5, 2003 04:24 AM
Howdy,
Thanks for pointing this up. I haven't used this construction before. I tend to mark the absolute path from the root. Would you mind sending me the example?
thanks!
Cheers,
Bob
Posted by: Bob Regan at August 5, 2003 09:33 AM
Hi Bob, you can get the example at http://ks.he.st/new/test_loadmov.zip
please note that in these files, i want the screen reader to read the content first and then follow by the header, this is because I want to test whether the tadIndex is working.
cheers
Posted by: Kim Seng at August 6, 2003 09:51 PM
Howdy.
First of all, this particular movie is simple enough that the default reading order is fine. If you are building a more complex movie from here, it is sometimes helpful to reverse the reading order just to be sure you are actually controlling it. You can always change the order around later. Finding a missing instance that is disrupting the reading order is trickier.
In this case, I found that reversing the reading order did not work. So I changed the reading order. I specified the values in the movie clip that contains them. In the parent clip the buttons were given values 4 and 3 (remeber - I am reversing the order for testing purposes). Then in each of the child clips, I gave the title and content values of 1 and 2, respectively.
This read backwards as I expected. i will send you the revised files if you would like to post them yourself.
Cheers,
Bob
Posted by: Bob Regan at August 7, 2003 10:14 AM
Hi Bob,
so you were saying that the tabIndex will work by using _level also? cool!
I would appreciate it if you can post the revised files.
thanks!
Posted by: Kim Seng at August 11, 2003 10:01 PM
Actually no. It worked when I moved the tabindex into the child movies. The tab index did not seem to work when it remained in the parent movie using the _level paths.
Sorry!
Cheers,
Bob
Posted by: Bob Regan at August 11, 2003 10:13 PM
Hi Bob,
if it doesn't work by using _level then I think it's kinda troublesome if we have 50 child movies (all the content pages) and one parent movie (the shell and the navigation buttons).
we will need to duplicate all the tabIndex scripts and put it in every child movies ?
Let say I have a flash movie consists of 2 levels. _level0 will have 3 buttons (A, B and C), when I click on any one of them, the respective content (contentA.swf, contentB.swf or contentC.swf) will load at _level1.
Since tabIndex will not work by using level so I'm wondering how should I organise my reading order?
I know that the below script that I put at the first frame of the parent movie(_level0) will not work properly.
_root.buttonA_btn.tabIndex=1;
_root.buttonB_btn.tabIndex=2;
_root.buttonC_btn.tabIndex=3;
_level1.header_txt.tabIndex=4;
_level1.content_txt.tabIndex=5;
is there any better way to solve the problem?
thanks!
ks
Posted by: ks at August 14, 2003 04:23 AM
Hi Bob, thanks for the files and now I got it!
For those who want to see the revised files that Bob has sent me, you can get it from
http://ks.he.st/new/test_loadmov_br.zip
cheers
ks
Posted by: ks at August 14, 2003 11:08 PM
Some comments related to tabIndex
Posted by: Anonymous at February 16, 2004 06:54 AM
You can also use the method .tabEnabled = true/false to 'silent' certain instances so they do not get called when the user tabs though the page (i.e. buttons, or clips that have invisible buttons attached).
May help someone sometime....
jk
Posted by: jeffKEYSER at March 17, 2004 12:48 AM
Hi I cant able to download the file , i to face the problem while tabing through the parent and child movie clips
Posted by: thiru at April 2, 2004 12:23 AM
Hi.
I have found these posts to be really useful, and I have successfully been controlling the reading order for text fields for Window Eyes. When I add a combo Box component the reading order totally screws up. Tabbing through the movie follows the tabindex orders I have set up but the screen reader still reads the page from top to bottom ignoring the tabindexes.
I am wondering if there are any examples of setting a reading order in a movie which uses combo box components.
sarah
Posted by: Sarah at October 21, 2004 09:11 PM
Hi can anyone help me with this?
I want to set tabs where i have 4 textboxes and 1 combo box in between.The tabindex property for the combo box does not work when i set the combo box's editable property to false.It gets the focus but does not move ahead onto the next textbox.i also dont want to change the editable property.
please help me with this
Posted by: Vikas at November 1, 2004 01:58 AM