How can I make a dynamic collapsible menu accessible? - html

I have an app that is using the footable plugin to allow for responsive tables. Essentially it takes columns from a table and turns them into a collapsible menu that is dynamically injected into the table as a new row when a user clicks a button to expand and then it is removed once the user collapses it again.
If you look at this example, it sets display: none on the columns but it also appends a new tr element that has a class of .footable-detail-row and that tr houses the menu that displays the data (you'll have to shrink your browser window to see this functionality).
This plugin does not have any accessibility built in unfortunately. I have forked their repo and am trying to make it accessible. I currently have it toggling the aria-expanded attributes and the span "buttons" are now buttons in my fork.
I am stuck on how I can make this accessible because the expanded menu content is dynamically injected into the DOM and then it is removed from the DOM once the toggle button is clicked again.
Perhaps I could add an aria-label for the buttons that says something like:
When this button is clicked it will toggle a menu that is inserted into this table as a new row immediately below this one. The new row contains additional column information. To avoid this button use a screen with a width of at least 992 pixels.
Obviously that's a gigantic label but it's descriptive as to what is happening and why. Thoughts?
If I only have a button like this: <button id="myButton" aria-expanded="false">Expand Content</button> I normally would add a aria-controls="myCollapsibleMenu", however, in this instance myCollapsibleMenu doesn't exist in the DOM.
Is there any way to make a menu like this accessible short of building out my own plugin like this that adds the menu when the script loads and doesn't remove the menu from the DOM?
I have looked into the other aria attributes like aria-live but is there a way to make this work with aria-live since these menus should be associated to a specific icon? Are there any other aria attributes I can use to make this accessible? Perhaps if I use an aria-describedby on the inserted row it would let the user know how this row relates to it the row above it.
I can add any attribute to the menu I want after it is created. Would it be acceptable to aadd a descriptive aria-label of what happens when a user clicks on the button?

The advice in the comments is the best advice, replace the library.
However, as with anything, there are compromises to be made and as you cannot replace the library at the moment, we can at least improve the accessibility to a level where it is "usable" with only a couple of minor tweaks.
Please note it probably will not pass WCAG AA if that is a requirement.
Stuff you have already done, just for clarity / to check
The first thing is to make the part that opens and closes the additional information accessible via keyboard and improve the semantics.
If you are able I would replace the contents of that column with <button> elements instead of just text with a click handler.
That gives you all of the relevant keyboard functionality you need.
Obviously that would mean finding and adjusting the click handler responsible for expanding the row and replacing it, but hopefully it would be as simple as changing the CSS selector.
button action
The second thing you need to do is indicate to screen reader users the action of the button.
This can easily be achieved with either an aria-label or use some visually hidden text (my preference due to compatibility)
This simply needs to explain that it reveals more information.
Something like "{name} (reveal all information in row below)".
a bit of tidy up with the icon and the button ARIA
Finally, let's hide that plus symbol from screen readers just to ensure it doesn't get announced using aria-hidden="true"
Oh and add aria-expanded="false" to the buttons and toggle that when the row below is added.
Quick example of desired output
An example of the desired HTML output (based on your fiddle) is below:
<td style="display: table-cell;" class="footable-first-visible">
<button aria-expanded="false">
<span class="footable-toggle fooicon fooicon-plus" aria-hidden="true"></span>
Annemarie
<span class="visually-hidden">(reveal all information in row below)</span>
</td>
</button>
Things you have not done yet that are still worth doing
You mentioned aria-controls, I would say use aria-owns instead (just a judgement call based on the slight differences, in reality it will not make much difference to user-experience).
Now as you have indicated you have an issue where the item that you want to point to with aria-owns is not in the DOM.
As such you can add this dynamically as a "best we can do" scenario.
So the second the new row is added to the table, add an ID to that row and then add aria-owns="your-id" to the controlling <button>.
The beauty is that if the row is expanded and the button gets refocused (or a screen reader user asks for the current element to be read out again) it will announce the relationship.
When the row is collapsed again, remove the aria-owns attribute.
example with aria-owns and aria-expanded="true"
Notice how I also changed the visually-hidden text to "close all information..." as the button purpose has changed.
<td style="display: table-cell;" class="footable-first-visible">
<button aria-expanded="true" aria-owns="your-new-id">
<span class="footable-toggle fooicon fooicon-plus" aria-hidden="true"></span>
Annemarie
<span class="visually-hidden">(close all information in row below)</span>
</td>
</button>
One last thing that would improve accessibility
Now that you have made it usable via keyboard and provided hints as to relationships there is one more thing you can do to improve the accessibility for screen reader users.
Add instructions!
I often encounter scenarios where a fix would take a long time but the only big issue with accessibility is actually discoverability (i.e. once you know how a widget is constructed and how to navigate it, it doesn't matter as much that it isn't perfectly formed.)
So have a button before the table called "help".
This can then explain the behaviour of the table ("click on a person's name in the first column to expand additional information in a new row below. Within that row a small table with additional fields will be added").
This simple step can really help screen reader users as they can go "ok so there is a button, if I press it there is a new row added, within that row there is a nested table" and know where to look for information.
Conclusion
Couple the instructions with the steps earlier and I am confident that although the table is not "accessible" it would be entirely usable and a reasonable experience for screen reader users and keyboard only users alike.
Obviously (for anyone else landing on this question) this is not the ideal solution, the point here is to do the best we can for now and plan to replace the current solution at the next iteration.

Related

Form control labels must be unique for buttons

I have a page with many buttons labelled "Buy". How can I make them unique? They aren't in a form.
Thanks
This message basically means that you must provide more precise context in the text of your buttons, because you have at least two of them with the same accessible text and they are so undistinguishable one from the other.
When using a screen reader, depending on how do you navigate, you jump directly to a given element, but skip over the elements that can give you more context.
In your case, for example, if I navigate by from button to button, I would be jumping from one "buy" button to the next, without being told what I'm going to buy because the information isn't on the button itself but next to it.
So it's absolutly required to give me more context, by extending the text of the buttons. The text in question isn't required to be visible on the screen, as it's a specific screen reader issue.
However, other people may also benefit from it if the text is also available as tooltip for example.
There are several ways to add the required context to your buttons.
The simplest is probably to use screen reader specific text also known as visually hidden text, like this:
<button>Buy<span class="sr_only"> basic package for 10$</span></button>
<button>Buy<span class="sr_only"> premium package for 20$</span></button>
<button>Buy<span class="sr_only"> full package for 40$</span></button>
Where .sr_only is a specific class from bootstrap. Other frameworks have similar CSS classes doing the same.
Pay attention to spacing so that words aren't uselessly glued together.
You may also use aria-label, like this:
<button aria-label="Buy basic package for 10$">Buy</button>
<button aria-label="Buy premium package for 20$">Buy</button>
<button aria-label="Buy full package for 40$">Buy</button>
Having the extended text in another element is also possible with aria-labelledby.
For both aria-label and aria-labelledby, in the label, pay attention to repeat the text actually shown on the button, as the accessible label completely replaces the natural text of the button (here, repeat the word "buy").
As a final note, it's also a good practice to shortly remind of the price, like I did here.
Depending on what you are selling, telling about the price late in the buying process (like just before checkout) can be considered as a dark pattern, and it's even more true with screen reader users, as they may miss indications that are obvious for sighted people.
There are many ways. Hopefully each button has a unique ID and so does something on the page containing text describing what the user would be buying. Then you can use the aria-labelledby attribute:
<button id="unique-thing-to-buy-button" aria-labelledby="unique-thing-to-buy-button unique-thing-to-buy">Buy</button>
Note that the ID's are space separated. This will announce the word buy followed buy the thing we are buying in a screen reader.
If not, you can create a translated string that accomplishes the same thing and use aria-label.
<button aria-label="buy unique thing">Buy</button>
Optimally, you would have something to improve the experience for sighted users as well. Putting a similar string in the title attribute to display on hover is a good start. Ideally you would use a widget that displays the same string on focus to cover your non-mouse users.

Is there a way to inform the screen reader about a transition to a new section on the same page?

I have a page that has 2 steps to register a user.
After a user has filled out all fields of the first section, he needs to confirm the "Terms and Conditions" and press a button to confirm it.
After he has pressed the button, first section is becomes readOnly and the second section (more fields to fill) appears at the bottom of the page and the page does a scrollTo this new section.
I need to inform the screen reader that there is a new section on the same page but I don't know who can I do it.
I appreciate your help!
In your html have an empty span/div with aria-live="assertive". In your button click function, add the text you want the reader to announce to that span.
(This is the same function where you will be taking focus to that section.)
Don't forget to empty it outside the function to make it announce properly next time also.
Aria-assertive text will be announced each time it is changed.
Eg.
In HTML
<span id="announce" aria-live="assertive"></span>
<button id="btn">Click</button>
In javascript
$("#btn").click(function(){
$("#announce").text("Scrolled to a new section");
});
This is about focus management. You need somewhere to anchor focus that makes sense to the user and you need to then move that focus.
This is not an ideal solution overall, but lacking context for the larger objective I'll give you the bits to get this part functional / useful.
First, add this style so you can see where the focus is going (you can remove/change it later):
*:focus {
outline: 2px solid #f00;
}
Now as you tab through the page you can see where the focus lives.
Then in your script where you create the new form (I recommend you actually just hide this section and display it instead of writing it in via JS, but I understand this may be a demo), update the <h3> to be focusable by adding an id attribute and then a tabindex so that you can drop focus on it. I use the <h3> you already have since it provides the context for the user and in this case overrides my general distaste for using tabindex on non-interactive elements.
<h3 id="second" tabindex="0">
Then add bit of script after your setTimeout() that moves the focus to that element (thereby ensuring it has been rendered and can receive focus):
var secondForm = document.getElementById('second');
secondForm.focus();
Now when you click the "Continue!" button, the page scrolls and the heading will receive focus, get announced (you can add instruction text, etc), and the user may continue.
You will probably need to massage the script a bit, maybe stuffing it in its own timer function to be certain it only fires when you want, but overall the general concept is in there.
I made a pen to demo it.

What to use for lots of 'details' links on one page. Web Accessibility doesn't like "details"

According to http://webaim.org/standards/wcag/checklist#sc2.4.4
2.4.4 Link Purpose (In Context)
(Level A)
The purpose of each link (or form image button or image map hotspot) can be determined from the link text alone, or from the link text and its context (e.g., surrounding paragraph, list item, table cell, or table headers).
Links (or form image buttons) with the same text that go to different locations are readily distinguishable.
and so WAVE (Web Accessibility Evaluation Tool - http://wave.webaim.org) says all my "details" links are not recommended on my page here:
but I can't think what would work better. I don't really want to clutter up the page with the first few characters of the actual details text because I think it would make the page look too cluttered.
Well, there are many ways you could solve your problem. To name a few:
You could add a title attribute to each link (i.e. title="Details on makeagoodpassword.com"), however screen readers might not read out the title attribute's values, so you'd better add aria-label="Details on makeagoodpassword.com" to your link tag
another (my preferred) option would be hidden text since this appears to be the most generic solution:
Details <span style="display:none;" aria-hidden="false">on makeagoodpassword.com</span>
Please also see: http://www.w3.org/WAI/WCAG20/quickref/#qr-navigation-mechanisms-refs for other options.

How to make a paragraph-granularity-editable document in GWT with paragraph meta-data

I want a UI that is basically a document having souped-up paragraphs that are (a) editable and (b) each have a column of meta-data/widgets on their left. That is, I want a tree layout that looks like an HTML document, except:
to the left of each paragraph is a column of controls like buttons, state indicators, very short textbox fields (3 chars), and
if you click on a paragraph (or hit an edit button on the left) it morphs into a textarea you can edit; when you are done, you hit a done button on the left (probably the edit button morphed into a done button) and the textarea goes back to being a paragraph.
When you hit edit, some labels in the meta-data on the left should also morph into text areas, etc. and back again when you hit done. Also, I want to be able to hit a button and show only part of the paragraph (imagine a paragraph having a title and a body).
I'm sure I can cobble something together that does this if I hit it over the head with enough HTML tables and GWT Panels, but I'm trying to do this in as lightweight manner as possible, given that such documents of these things may be large, I want it to resize naturally in the browser, and since browsers already naturally lay out things that look like documents I should be able to use very vanilla HTML for most of it.
I've spent several days being frustrated with GWT Panels of various kinds. Ideas?
You should just be able to hide a Label and show a TextArea, and then switch back when you're done editing. Set whatever styles you need to on them - I think a Label comes out as a <div> and a TextArea comes out as a <textarea>. No panels required... just a <div> container to put these two widgets in.

Collapsible table in HTML Email (Outlook 2007-2010)

I've sent various HTML emails in the past, and have seen the pretty large limitations associated with it. What I really need is the ability to have regions with a show/hide ability - click the plus sign or a header to toggle.
I'm figuring JS is out of the picture, CSS might be a possibility. I only need it to work in Outlook 2007-2010. Any suggestions?
Thanks!
You can do this in Outlook using anchor tags. The trick is to create 2 tables that are separated by a td cell with a large height specified so that you don't see the second table.
Both tables are exact duplicates except that table 1 has the show link, while table 2 has the content you want to show, and a hide link.
When you click the anchor tag, the email moves down to the position specified in your second table. As the content in both tables is the same except for the show/hide box visibility, you've created an illusion that the box is toggling.
If you have more than one show/hide box, you'll need to create more tables. The email will get really long, but the toggling effect still works in Outlook.
The anchor tags:
Click here to show content
<a name="section1"></a>
Here's a quick example: http://jsfiddle.net/mjcookson/nq3Re/
Update to comment: Also, your email might not fill the entire viewport, so a gap between tables is used to avoid seeing the second table immediately after the first table.
You can't do that in Outlook. Its HTML email rendering engine is pretty bad. I have seen it done for the mobile webkit and android browsers.
See this article: http://coding.smashingmagazine.com/2011/08/18/from-monitor-to-mobile-optimizing-email-newsletters-with-css/