I am delving into the confusing world of web accessibility and trying to retrofit my HTML code to have better accessibility with things such as aria-labels etc.
Trying to tab through my webpage app-header, I am not able to select the page title... Should I be able to, or am I worrying about nothing?
The burger menu and the search bar icon are able to be tabbed. I'm just wondering whether the text should be? Because it is not being read out either.
FYI: I am using ChromeVOX as a screen reader
<app-header class="topHeader" fixed shadow slot="header"> <!-- effects="waterfall" not needed as nothing scrolls behind header bar -->
<app-toolbar>
<paper-icon-button id="toggleDrawer" icon="menu" on-click="toggleMenu" title="Expand menu" aria-title="Expand menu"></paper-icon-button>
<div main-title>App Header Goes Here</div>
<search-bar></search-bar> <!-- This is an external element being called in -->
</app-toolbar>
</app-header>
Does clicking on it do anything (navigate to another page, open up a new set of options using DOM manipulation, etc) that isn't behaviour duplicated by some other control?
If so, then it should be possible to tab to it.
If not, that isn't needed.
(If it does nothing, then it is counter productive to allow it to be focused).
Related
I am trying to implement the notification component that will show the list of the items and will be opened by clicking on the notification icon on the fixed navigation bar on the top. I don't think it's a menu bar. Because the menu provides the actions that can be performed and it can also have a sub-menu.
https://www.w3.org/TR/wai-aria-practices/#menu
Can anyone let me know what should be the aria-role of such kind of components?
Below is the code sample. I will open the template dynamically by clicking on the notification icon button:-
<button aria-label="notifications">
<mat-icon class="mr-md">notifications</mat-icon>
</button>
<!-- Notification template -->
<div class="notifications__item">
Notifications
<li *ngFor="let notification of notifications" class="notifications__item">
<mat-icon class="notifications__icon material-icons-round">
{{ notification.icon }}
</mat-icon>
<div class="notifications__content">
<div [ngClass]="{ 'notifications__warn': notification?.type }">
<span>{{ notification.title }}</span>
</div>
<div>{{ notification.description }}</div>
</div>
<small class="notifications__caption">
{{ notification.duration }}
</small>
</li>
</div>
There are still a lot of things to consider that your example doesn't cover, so this isn't a complete answer, it is just pointing you to the relevant WAI-ARIA depending on what route you take.
The button
The first thing to consider is the button. You need to tell screen reader users what state it is currently in. For this we use aria-expanded to indicate whether the item it controls is currently opened or closed. (aria-expanded="true" for open, aria-expanded="false" for closed.)
At the same time we want to indicate what item this button controls (as the notification list isn't 'owned' by the element - for example if it was an <li> with a nested <ul> in a menu then the list would be 'owned' by it).
For this we would use aria-controls or aria-owns and point it to the ID of the element it controls. For the difference between them see this stack overflow post as a good explanation, in this example I would say it is aria-controls but yet again depends on your implementation and positioning in the DOM.
With regards to the button itself and where it sits in your menu, this is still considered navigation so it should sit within your <nav> element. However if this sits outside of your navigation along with say a 'help' and 'account' section you may consider those items part of a toolbar. (yet again I would say it doesn't apply here but something to look at)
Also it doesn't appear to be applicable here but if you include any links etc. within the 'popup' / modal that shows the notification list (i.e. a 'view all notifications' link), you should consider aria-haspopup="true"
The notification list
Right so we have a button pointed to the container (don't forget to give the container the relevant ID for aria-owns or aria-controls). Next what about the container itself?
Well in this example it appears that the container should be treated like a modal.
So for this reason you need to consider:-
trapping focus in the modal,
close with Escape,
returning focus to the button that activated it on close,
providing a close button that is accessible by keyboard,
a title for the modal (even if it is visually hidden)
What I would recommend is add some of the accessibility features above, try it with a screen reader and keyboard and see if it is easy to use. Once you have decided on your pattern ask some more questions on specific use case issues as the above is general guidance.
A few things to consider based on your markup
Additional things to consider from your example:-
use aria-hidden="true" on your icons, they don't add anything for screen readers (assuming your notification.title is descriptive).
For the notification title consider making it a relevant heading (<h2> - <h6> depending on position in document.
Don't forget to add some visually-hidden text that describes the warning level (I can see you have some form of colouring / distinction in [ngClass]="{ 'notifications__warn': notification?.type }" - expose the same info to screen readers.)
You currently have a <li> within a <div> - maybe change the outer <div> into an <ul> so it is semantically correct (<div class="notifications__item"> into <ul class="notifications__item">)
I hope the above is useful to set you on the right track, a lot to read but after reading the linked articles you should be able to make a better decision on what pattern you are using (as I didn't even mention making this a sub item within your menu) and can then ask some more questions on specific details you don't yet understand.
final thoughts / tips
test with a screen reader - this is the biggest tip I can give on working out how WAI-ARIA works and interacts with things.
Also if you are ever in doubt as to whether a WAI-ARIA attributre is applicable it is better to not include it.
Incorrect use or WAI-ARIA is actually worse than not including it at all so make sure you understand when to use an attribute reasonably well before implementing it. If I am ever unsure (as it still happens to me!) I tend to look at 2 or 3 examples of it in use and see if my pattern fits the examples I looked at.
I've been having problems trying to work with paper-icon-button with Polymer. My code so far is very simple. The website generates the space that the icon uses and reacts with the right behaviour to respond to the mouse's events but the icon doesn't show up
<paper-toolbar class="gallery_header">
<paper-icon-button icon="menu"></paper-icon-button>
<span title class="flex">Admin</span>
</paper-toolbar>
The scripts that are being loaded in order are:
webcomponentsjs
polymer
iron-icon
bootstrapiron-ajaxiron-imagepaper-drawer-paneljquerypaper-header-panelpaper-stylespaper-icon-buttonpaper-toolbarreact
What you need to do extra in order to make that menu icon appear is to import the iron-icons element which is just a collection of SVG icons. For more information about the iconsets and the iron-icons element, you can check out Rob Dodson's episode on this topic from the Polycasts series.
Right now at my job, I'm tasked with creating a monitoring dashboard site. I'm thoroughly looking through a lot of different design choices and what my company wants, but all the templates I'm looking at for dashboards aren't formatted the way the company wants: a nested tab feature, not a side bar navigation.
Upon looking through a bunch of nested tab examples, one of them caught my attention which was Zozoui's Nested Tabs. This isn't something I've seen from BootStrap and JQuery UI, so I don't even know how to begin with starting something like this, but I'd like to change a couple of things here and there, like right before the second set of tabs, have a description of the first current tag.
So in short, how do I create my own nested tab feature like Zozoui's Nested Tabs?
You can make a menu and a div for contents when you click a specific tab it's contents should show in that div.do it by jquery or js.
HTML
<nav id="menu">
<a id="item1">item1</a>
<a id="item2">item2</a>
.
.
.
</nav>
<div id="contents">
<div>
jquery
$("#menu a").click(function{
$("contents").html(//something that you want);
});
jquery mobile newbie -- I inherited this project.
I have quite a few 'pages' in my jquery mobile app. On each page I have a nav panel. Each page is set up much like this:
<div data-role="page" id="help_manual" data-theme="d">
<div data-role="panel" id="navpanel_help_manual" data-theme="d" data-display="overlay" data-position="right">
<div data-role="controlgroup" data-corners="false">
Home
User main menu
</div>
</div>
<div data-role="header" data-position="fixed" data-tap-toggle="false">
<a data-icon="bars" class="ui-btn-right" style="margin-top:10px;" href="#navpanel_help_manual"
data-iconpos="notext">Menu</a> <!-- this is the button that actually brings up the above panel-->
<h3>User Manual</h3>
</div>
<div data-role="content">
BLAH BLAH CONTENT
</div>
<div data-role="footer" data-position="fixed" data-tap-toggle="false">
Back to main menu
</div>
</div>
This all works well and good.
Then you make another page. ... Then another... Then another... Suddenly you've got a few dozen pages all with their own 'menus'. They all work, but there is a LOT of redundant code, given all the menus are identical.
Now I want to make a change to all of the menus.... and instead of modifying one 'navigation panel' I have to make the change a few dozen error-prone times.
I have tried simply taking the 'panel' code and moving it outside the 'page' div... but that results in, effectively, a 'new' 'page' when the button is clicked. Other attempts at moving the various parts of this code around are similarly broken.
An include could remove the 'list' from the 'core' of the control group... unfortunately, that still leaves a lot of redundant code and I've got one fun tweak: This page needs to be able to work offline. The purpose of this app is to be able to go offline, collect data 'in the field', and come back and upload it. So a SSI isn't an good option.
Help?
Here is a JsFiddle with multiple pages and the panel written only once.
You should write your panel once outside the page. (If you have one file per page, just write the panel outside the index page as a sibling of the page) :
<div data-role="panel" id="navpanel_help_manual" data-theme="d" data-display="overlay" data-position="right">
...
</div>
<div data-role="page" id="help_manual" data-theme="d">
...
</div>
Doing so and as it becomes an external panel. You should then initialise it manually.
$('#navpanel_help_manual').panel();
The panels below are all located outside the page. Panels outside of a page must be initalized manually and will not be handled by auto init. Panels outside of pages will remain in the DOM (unless manually removed) as long as you use Ajax navigation, and can be opened or closed from any page.
The application I am developing consists of several major sections. To this end, I have a global toolbar for the entire application and a toolbar that is specific to the particular section of the application.
Here is a gist that demonstrates what the view for an individual application might look like:
https://gist.github.com/mattjonesorg/33b2bbcb0b0c81feb5ca
(Paste the gist into the polymer designer for a quick view)
I have the main application's toolbar as a core-scroll-header-panel. The submenu is in the content. The problem is that the submenu is scrolling under the core-scroll-header panel, which I can easily see as by design, but I'm hoping somebody has a tip for allowing me to keep both the main core-scroll-header-panel and the toolbar locked at the top of the screen. I've tried nesting a core-header-panel in the section, but that did the same thing.
My actual application is in Dart, but I'd be happy with a Javascript answer.
Thanks in advance,
Matt
You have the submenu core-toolbar nested in the scroll region (the <section id="section2" content>). If you want it to stay, put it before that scroll region:
<core-toolbar id="core_toolbar" class="tall">
...
<div id="div1" class="bottom indent">Title</div>
</core-toolbar>
<core-toolbar id="core_toolbar1">
<core-icon-button icon="menu" id="core_icon_button3"></core-icon-button>
<div id="div2" flex>Submenu Toolbar</div>
</core-toolbar>
<section id="section2" content>
<p id="p">Hello, World</p>
...
If you want the both to stay put on scrolling:
<core-scroll-header-panel fixed>
If you want just the submenu to stick:
<core-scroll-header-panel>
If you want the header to condense and have them both stick:
<core-scroll-header-panel condenses keepCondensedHeader>