Background
I have a site which has a master/detail sort of design. The master view is a column chart where clicking on one of the columns (each column represents one month) changes the detail view (which is a nested table listing some details of that period). I've started an accessibility audit and as you might imagine, it is not very accessible. I solved the chart by adding aria-hidden="true" and adding an invisible table with the same content with buttons in the month rows. Now activating the buttons will do the same thing as clicking the chart columns - change the detail view.
Moving focus
When the button in a table in the master view is clicked, my screen reader (VoiceOver Safari in this case) reads "Button clicked", but then using the cursor keys keeps reading the table. I assume a user once they decide which button to click would like to read the detail view and so I would like to move them there.
What I have tried
I changed the buttons to <a href="#detail-view" ng-click="loadDetail"> and gave the detail view container div the id="detail-view". This doesn't seem to do anything.
Simple answer: don't. Shifting focus around on a non-sighted user is actually an accessibility violation. See WCAG criteria 3.2.2.
In short, you shouldn't initiate a change of context automatically after the press of a button or other control interaction. What you should do is inform the user of the new content, either by an announcement, or by providing a description of the change in the accessibility text of the control itself. An example of providing this context would be announcing your master cells as "tabs". Just the simple association of a button behaving as a tab provides a lot of information!
To make your application more accessible you should ensure the user knows they are in a master-detail type of control, by providing proper role information (I find "tab" most likely here, but other roles may be applicable). Also, provide a heading at the top of the master view, and the detail view, so that they can easily navigate between the two. As long as they know where they are, and can easily navigate to important areas of the page, they are fine. Automatically shifting focus around is actually an accessibility violation, and should be avoided.
Related
I have created a document schema that includes a captioned_image node type, which references an image in a separate CMS. The image has a caption and a credit, which I'd like editable in the document. When the user edits the content in the ProseMirror editor, I can take note of the change and send a request to the CMS with the updates.
However, the caption and credit fields can be "locked" when another user is editing the image in the CMS.
How can I make the caption and credit child nodes of the captioned_image node non-editable, when those fields are locked by another user? A selection shouldn't be able to be placed in a position.
I can think of two ways
When a piece of the document is locked, filter transform actions, canceling (resetting to the old state) any that touch this region (can be determined by calling forEach on the elements in action.transform.mapping.maps).
Write a custom node view for these kinds of nodes, and give them an attribute readOnly. Toggle it when they should become uneditable, and when it is on, render the locked content with contenteditable=false. But note that this does not protect against programmatic changes to the content. Also, it will make it impossible to put the cursor into them, which might not be desired.
From an end user point of view. If I have a list of vertical divs with different content in each div, should I provide up/down arrows to reorder the divs or should I allow the user to drag and drop the divs into a particular order?
Drag and drop would allow the user to place the div anywhere in the vertical list but may not be obvious to the end user that the divs are movable.
An up/down arrow beside each div would provide visual cues but would be awkward for the end user if they wanted to move a particular div up or down by a large number of places.
In relation to the above, I am biased towards drag/drop due to my use of Moodle for teaching. We did have a training course which overcame the visual cue issue. I'm aiming my app to be as user friendly as possible without having to teach the user too much (if anything).
Is there a particular CSS styling for a div that provides a cue - like a gripper hand to drag and drop and can I place some kind of visual cue around the div using CSS.
Any input is most welcome and I hope you understand what I'm trying to achieve here.
P.S. The vertical list can be quite long.
You may get some better answers to the usability questions on the User Experience Stack Exchange. My own anecdotal experience having used an interface where items could only be moved up or down one item at a time in a long list was that it was a total pain, and when drag-and-drop was finally implemented, it was a breath of fresh air.
I also have conducted a usability test (task 1 in this PDF) where a simple label of "Drag to add a new ..." (it was a duplication interface, not a reordering interface) on top of some pill-shaped elements (with a "grabby hand" cursor and change of color on hover) was quickly discovered by 8 out of 8 users without any prompting.
As for your technical questions, there are a few different CSS cursor styles you could implement (in particular, cursor: move;, cursor:grab,cursor:grabbing (my preference is for 'grab' on hover and 'grabbing' while dragging). I've shown some here: https://jsfiddle.net/xnho95oL/, as well an idea for some "placeholder" elements that might appear (and could presumably expand or otherwise change appearance when dragging an item over them).
I've posted a couple of Google Charts accessibility questions already; here's one more. Thank you in advance for your help.
Google Charts tables are surprisingly easy to make accessible to blind users, but I'm running into a perplexing problem. I'm making a website that uses standard Google category filters to produce a data table. I've added ARIA-live=polite and ARIA-atomic=true attributes to the table to signal screen readers to read out the entire table when it changes. This works perfectly most of the time; when a control is changed, after reading out the control behavior the screen readers will immediately start reading the new table.
Unfortunately, changes in class attributes trigger ARIA-live. For Google Charts tables also tagged with ARIA-atomic, this means that row hover behavior will trigger a reading of the entire table, because hovering over a row changes the row class. And if you move the mouse pointer over more than one row, it'll read out the entire table once for every row over which you pass.
EDIT: see NOTE below to clarify this paragraph. I've tried addressing this by tweaking the table's cssClassNames options, but the results are frankly maddening. Even when changing the tableRow and hoverTableRow options to the same class, the table will only apply that class when hovering, changing the class to " " when not hovering.
I've tried convincing my co-workers that users of screen readers won't be using mice, but I've been asked to find a solution anyway. Guh.
Does anyone understand how this row hover behavior works, exactly? Is the problem as inscrutable as I'm making it out to be, or am I missing something? Does anyone have any ideas for a workaround?
NOTE: Ryan B has a good workaround idea (see comment below), and that's exactly the kind of solution I'll propose if my co-workers insist that the current setup doesn't meet their standards. Thank you Ryan.
Still, in the hope that the problem is with my explanation, I'll clarify: when you hover over a row in a Google charts table, the background color changes. The Google Viz script manages this by listening for hover events over table rows. On hover, the script changes the row class name from something like "tr-goo-viz-table-row" to "tr-goo-viz-table-row-over", both of which are in the Google Viz CSS and only include styles of background colors (white and light grey, respectively).
In the HTML table call one can set the cssClassName option for hoverTableRow to "tr-goo-viz-table-row" (or set both tableRow and hoverTableRow to any class that only sets the background color) and visually, the hover behavior stops. But in an odd quirk, the script insists on differentiating the class names on hover even if you're telling it to keep the class names the same. Depending on the implementation the script will produce a doubled class name ("tr-goo-viz-table-row tr-goo-viz-table-row") for hover rows, or an empty class name ("") for non-hover rows, and either way that'll still trigger ARIA-live even though no style change is implemented and hovering has no visual effect.
Since I don't understand the implementation of this behavior, I'm hoping someone who understands it better than I do might know of a way to stop the hover-triggered class name changes altogether - killing the listener, etc. Something like adding "pointer-events:none" in the row CSS for example...except pointer-events wasn't supported in IE before IE11 and the people using this website will mostly be using IE9.
I currently have an app that has five components. On the left I have a radio button field and a grid below it, on the right I have a display field, chart, and another grid [top to bottom]. The radio buttons filter every other component by a certain date, and the left grid [when selected] will filter the right components by the selected object.
Currently the app does what is needed, but when I select a few radio buttons in a row OR select a few objects in the grid, the app will eventually totally disappear. I tried running the app externally and internally with a custom HTML app, but the problem does not go away.
Here is a picture of the app before anything crashes:
Interestingly, when I look through the chrome debugger and look at the Elements tab, I see there are lots of masks that have been created and not destroyed. Here is a picture of a slight piece of the HTML that looks fishy and occurs after I select a few objects from the left grid:
Every time I select a new object, one more mask will be added to the DOM. I don't know if this is what breaks my app, but it seems odd so it may be related?
I didn't include any code because I thought it should be some easy fix - plus, the code does exactly what it should [before it disappears]. Any help on how to fix an app that disappears would be great!
In itself a mask sticking around to be reused after data loaded successfully is not an indication of a problem. I see mask being created and not destroyed in a simpler app:
Perhaps what you experience is an issue of timing when elements load asynchronously.
I'm not sure this is even possible. I have a UI built that uses javascript and css, the interface users use a keypress to navigate. Css for the layouts that change per client, like a "skin". Javascript controls the functions and monitors the users keypresses.
The setup has 2 menus, a lower one and upper one. When you load it the lower one is focussed and you can use left or right arrows to go between the menu items.
In normal circumstances you would press "up" to get an upper menu, however this one client does not want this menu at all.
The problem is that we cannot just simply edit the javascript to prevent it, since the same javascript is used for all the clients, only different css get loaded based on which client is selected.
So now I have the upper menu hidden, but the problem is that the javascript still allows you to press up, but now since the top menu is not there, you lose your focus, and nothing is highlighted. The end user doesn't know why or how they lost focus if they press up by accident. (since they know no different setup where the top menu is there, they don't realize that they should press down, they just know nothing seems to happen when they press left/right)
What I want to do, is somehow, in the css, prevent the users from pressing up. Since we can't just go change the javascript.
Is this possible? Or is my only solution to modify the javascript?
TIA!!
Thanks to all who offer advise, just to clarify, we will make a new release with a function to check if the client wants this other menu, and disable the up button if not, however that will require a new release of the software, and a full pass through QA. Just trying to quick hack this one client in the mean time.. :)
Our final solution would have a boolean field in the database, and if it's true, the javascript will have an ignore for the up key, if false, then act normally.
Change the code so it only acts on up-arrow key-presses if an element isn't present.
EG add a p with the class="noupkey" then stop the event from firing like :
if($('.nokeyup').length === 0) {
//Do normal behaviour
}
Unfortunately there is no correct way to disable components through css, for this type of functionality is meant for javascript.
The philosophy for most programmers that I have worked with is that you should allow the end user to decide if they want to use a new feature.
What I mean by this, is that you should leave an option in the app that lets the person disable the component themselves. This way you can have the same set of javascript for all users and still disable any component in the correct way. The real advantage to this is that you wont have to deal with this ticket ever again, the support staff could simply walk any client through the operation of recreating the requested feature.
Most of this solution might be unusable to you however. I understand it's not easy changing your workplace convention.
Here is something that might be a little more useful, How do I disable form fields using CSS? Some of the advise might be applicable to any component, including menus.
Actually it is very odd solution but it can be done with little tricky solution .
Make One transparent Div with more z-index , with Absolute Position at the body level over that Up Button , For rest of your applications apply Pointer Events Css property to none so your mouse events will be done on the Below Div .
Then for your Case in which you want to disable that control do not give Pointer Events to the foremost div it will be disabled for mouse events .
Note : There is some issue for Pointer events in IE.