The Situation
I have an area of the screen that can be shown and hidden via JavaScript (something like "show/hide advanced search options"). Inside this area there are form elements (select, checkbox, etc). For users using assistive technology like a screen-reader (in this case JAWS), we need to link these form elements with a label or use the "title" attribute to describe the purpose of each element. I'm using the title attribute because there isn't enough space for a label, and the tooltip you get is nice for non-screen-reader users.
The code looks something like this:
<div id="placeholder" style="display:none;">
<select title="Month">
<option>January</option>
<option>February</option>
...
</select>
</div>
The Problem
Normally, JAWS will not read hidden elements... because well, they're hidden and it knows that. However, it seems as though if the element has a title set, JAWS reads it no matter what. If I remove the title, JAWS reads nothing, but obviously this is in-accessible markup.
Possible Solutions
My first thought was to use a hidden label instead of the title, like this:
<div id="placeholder" style="display:none;">
<label for="month" style="display:none">Month</label>
<select id="month">...</select>
</div>
This results in the exact same behavior, and now we lose the tool-tips for non-screen-reader users. Also we end up generating twice as much Html.
The second option is to still use a label, put position it off the screen. That way it will be read by the screen-reader, but won't be seen by the visual user:
<div id="placeholder" style="display:none;">
<label for="month" style="position:absolute;left:-5000px:width:1px;">Month</label>
<select id="month">...</select>
</div>
This actually works, but again we lose the tool-tip and still generate additional Html.
My third possible solution is to recursively travel through the DOM in JavaScript, removing the title when the area is hidden and adding it back when the area is shown. This also works... but is pretty ugly for obvious reasons and doesn't really scale well to a more general case.
Any other ideas anyone? Why is JAWS behaving this way?