Where focus should be set if HTML element removed? - html

I have HTML (simplified) like this:
<ul>
<li><a id="1" onclick="removeItself(1)" href="#">first</a></li>
<li><a id="2" onclick="removeItself(2)" href="#">second</a></li>
</ul>
<input type="text"></input>
If the one of the links is clicked it will be removed. In my case after removing, the whole list will be rendered again.
There are many questions, but the general is where to set focus if element with focus is removed?
Where should be focus set if e.g. the second list element is removed or if all elements are removed?
What solution is web-accessible in this case? Is it acceptable to set focus always on the first item in the list, but if all items are removed to set focus to the next (input) or to a previous element?
In IE the focus will be reset and it will start from the beginning of the page.

The general principle I would apply here is:
if a next element exists, place the focus on the next element,
otherwise, if a previous element exists, place it on the previous element,
otherwise, place it on some element before or after that makes sense, of there is none, then do nothing
Here is the Angular.js TodoMVC application that I have modified to behave this way (although you could argue that I have not done a good enough job on #3 from above)
http://dylanb.github.io/todomvc/index.html#/
Here is a blog post on the process of making the delete work
http://unobfuscated.blogspot.com/2015/02/angularjs-accessibility-deleting-todo.html

This is what I did based on the answer for question Where to put focus after deleting an item in a list
Following the principle of Least Surprise, I would leave the space open with "[deleted]" in it til the cursor moves off the list, at which point the gap can be closed.
Given:
Say there are 3 items in a list and user uses up / down arrow to navigate and focuses on the second one.
User Action:
There is a delete button inside the list item, user tabs onto it and presses enter.
Context Feedback:
After deletion succeeded, focus will be placed on an invisible item at the original place where the second item was, and this invisible item contains text "Deleted" (screen reader will announce "Deleted").
Clean Up:
Then user can still use up / down to move focus to the previous / next item (or what you implemented before), and invisible item would be removed after onblur event triggered.

Related

How can I make a dynamic collapsible menu accessible?

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.

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.

Focus is changed when inspecting element with CTRL+SHIFT+C

When I want to inspect an element in the browser with either CTRL-SHIFT-C or by clicking , the current focus is changed, possibly leading to elements that was previously visible not being visible any longer.
Is there some way of avoiding that?
You can select the element you need focus on in the Elements panel. Then find the :hov toggle (As of V49 iirc, 48 may still be a thumb-pin icon) which will open a menu for toggling given element states. From there, just select the one you need applied (focus in this case.) That will force the given state even if focus is somewhere else.

How does tab-press work in HTML page

I got some problem when user pressed the TAB-key. There should be a static way in which the user can jump from one form element to the next.
I know there is a posibility to declare in which order the elements should be selected with TabIndex.
Now I would like to know how does the browser decide which element is focused as next Element after pressing Tab.
EDIT: Does it only walk down the dom or does look it on the position on rendered Website, that's what i want to know.
The process of deciding in which order to skip from one focusable element to the next is fairly complex. The first step is to find out, which elements may gain a tab focus.
There is an article by Maks Nemisj that covers your question in length: “Focus, tabIndex and behavior of browsers”.

hyperlink to open different web page with specific element in focus AND active

This problem refers to the main (header) nav menu on THIS PAGE.
When any of the items in the "Services" drop-down submenu is clicked, I want the "Services" page to open (in the existing browser window) AND for a specific anchor tag element on the "Services" page to be in focus. I've achieved this OK. BUT, when the targetted anchor tag is in focus, I want it to also behave just like a manual mouse hover had been performed on its parent div, ie there should be a slide-down of text corresponding to the focussed element.
For a manual demo, go HERE and hover on one of the vertical list items - text will slide down to the right of the list.
HTML for the "Services" submenu link:
<li> collaborative law</li>
HTML for the targetted "a" tag and its parent div (ie "a" tag that should be in focus on "Services" page):
<div id="mylist1"><h3>Collaborative Solutions</h3></div>
Script to drive the hover behaviour of the focussed "a" tag and its parent div:
//fades in desired text after fading out whatever text is already displayed:
$(document).ready(function() {
$('#mylist1').mouseover(function() { //note first list item must be called mylist1 to avoid conflict with other code
if ( !$('#text1').is(":visible") ) { //prevents re-display if desired text already displayed
$(".shownText").slideUp(100).removeClass('.shownText');
$('#text1').slideDown(300, 'linear');
}
});
//capture click events as well:
/* $('#mylist1').click(function() {
if ( !$('#text1').is(":visible") ) { //prevents re-display if desired text already displayed
$(".shownText").slideUp(100).removeClass('.shownText');
$('#text1').slideDown(300, 'linear');
}
});*/
//capture focus events on <a> as well:
$('#myTag1').focus(function() {
if ( !$('#text1').is(":visible") ) { //prevents re-display if desired text already displayed
$(".shownText").slideUp(100).removeClass('.shownText');
$('#text1').slideDown(300, 'linear');
}
});
});
Note the main nav menu has been created using jquery, via a Dreamweaver extension.
What I have so far:
When the "Services" page opens, the correct target is in focus (as shown by the browser address bar). However, this focus is not triggering the expected text slide-down event. When I hit tab, the next list div goes into focus (as expected) & the appropriate text slide down occurs.
Am I hoping for too much? Have I misunderstood the limitations of 'in focus'" Will Mt Hotham have a killer snow season this year ?
Your sage advice is greatly welcomed!
Kirk
I'm not sure your use of "in focus" is quite what I expect... Having a fragment in the url doesn't necessarily give focus to that element, it just moves the display down to it. I assume the reason it works for tabbing is that tabbing does focus on elements and I assume it starts at the element that has been scrolled to.
What I'd suggest is breaking out your display script into a named function (so it can be used from elsewhere) and then on page load you can pull out the fragment from the url (eg #famLaw). Using that fragment you should be able to find the right element on the page and focus it.
It should be noted also that pulling the display text into a separate function has the advantage of consolidating your code - you are basically duplicating the code in the onfocus and onready events so breaking it out makes for easier maintenance and reuse. :)
P.S. I guess yes for Mt Hotham. I'd never heard of it before but I'm going to be optimistic.