After a decade long hiatus I am dipping my toes into web development again. It still seems a very confusing heap of constantly changing standards to me, making it unclear which browsers support what and what the best practices are.
Currently, I am focusing on using the new semantic elements of HTML5. I found out the ASP.NET Core default Bootstrap template does not use the <nav> element for the navigation bar and was therefore looking into how to apply it properly.
The default navbar template in Bootstrap does recommend to use <nav>. However, I am confused as to what the purpose is behind the aria-expanded attribute applied to it. After learning about the benefits it offers to screen readers (indicating whether the navigation bar is collapsed or not, in this instance when the screen size is small, i.e., for smartphones), I am still confused as to whether it should be there at all. (And whether or not aria-controls should be applied, which it isn't in the default bootstrap template.)
Let me explain:
Some of these aria attributes seem to be describing visual behavior. Does it even make sense to describe something to the non-sighted which they can not see?
With the <nav> and <main> semantic elements applied correctly, don't the screen readers have all the necessary information at hand already to quickly skip the navigation bar (equivalent of hiding it for the sighted)?
Wouldn't a better alternative be to just hide the navigation toggle mechanism to the non-sighted altogether? Here my question then would be, how to go about this. Can a button be hidden using role="presentation" and/or aria-hidden="true"?
Using the example you cite at https://getbootstrap.com/examples/navbar/, it needs aria-expanded.
In the larger viewport, the "dropdown" menu hides all the sub-items. They are not only hidden visually, but hidden to screen readers as well. The aria-expanded helps give the user context whether or not there is more available, and also gives some clue about where the subsequent tab-stops may take the user.
In the narrower viewport, where the navigation becomes a hamburger, this still applies. Doubly so since it also applies to the hamburger itself.
This context is important since aria-controls support is poop (to quote Heydon).
There are cases where every item in a menu is available via tabbing, even if visually not there. In that case aria-expanded is not so important, but aria-controls would have more value.
Separately, that menu needs better :focus highlighting for sighted keyboard users, and DOM sequence for the menu versus logo in the narrow viewport (through that is my opinion).
Some of these aria attributes seem to be describing visual behavior. Does it even make sense to describe something to the non-sighted which they can not see?
That question should be the first to appear in any ARIA tutorial.
With the <nav> and <main> semantic elements applied correctly, don't the screen readers have all the necessary information at hand already to quickly skip the navigation bar (equivalent of hiding it for the sighted)?
And this one the second.
Edit: When I read those questions, I thought "that guy has already understood everything". ARIA tutorials rarely answer those questions because they are context dependent, but asking those questions must be the first step before using ARIA. Eg. image carousels are for blind people a very different user experience. Giving an aria-controls attribute to the "previous" button does not give more intelligence to a system based on visual effects. ARIA is not a miraculous panacea.
ARIA may be seen as a kind of magic potion for people wanting to make accessible something which is not accessible. In many cases it will be used ill-advisedly.
The aria-expanded can give a good user experience for screenreaders, informing whether or not an element can be opened to show more elements (for instance inside a dropdown menu).
You can't apply the aria-expanded directly on a nav element because it has to be set on an interactive element (like a button) to inform that this controls the visibility of another element inside the same container (which can be a nav).
The better alternative I can see is not hiding anything to also help people not using screenreaders. Instead of collapsing a navigation bar at small screen resolutions, it's perfectly possible to:
always show it
display a persistent menu icon to jump to the menu bar (or temporarily displaying it inside the viewport)
This has the benefit to enable the possibility to scroll to the menu bar (for people not understanding what that icon with three parallel lines may indicate) and let screenreaders users list all the internal links.
Of course, things are very different if you conceive a web application rather than a simple web site, and ARIA might be more useful in that context.
Related
I need to show certain content in a modal/fullscreen panel on small devices, triggered by a button. On large devices, this same content, is just always shown and the trigger is then hidden.
How do you approach this for accessibility?
Currently, I have this setup
<button type="button" aria-expanded="false" aria-controls="filter-panel">Filter</button>
<div class="o-panel" id="filter-panel">Form</div>
Initially, the o-panel is hidden on small devices via CSS (in a media query that targets small devices). I set aria-expanded to true when the trigger is hit, and add an active class to the panel itself, which shows the fullscreen o-panel via CSS. On large devices, I hide the button and always display the content from o-panel via CSS (in a media query that targets large devices), inline, where it is found in the HTML.
Does this make sense for accessibility? My panel doesn't say role="dialog", becuase on large devices it's just content, not a dialog. Is it a problem that my button is hidden on these large devices?
I'm really stuck at what I should do here. If I add role="dialog" to my o-panel, should I remove this property for large devices, where it is actually not a modal?
Or should I move copy/move the content from my o-panel in a div with role="dialog", in case the trigger is hit? I just don't want two copies of the same content.
On large devices you need to do a couple of things.
Hide the button properly
First make sure the button is display:none, not visibility:hidden or anything else or it will still show up in the accessibility tree.
The main (<main>) problem
A modal should appear outside of your <main>.
This is so you can add aria-hidden="true" to the <main> element when the modal is active, so as to stop people navigating outside of the modal on a screen reader. (Screen reader users use headings, links etc. to navigate a page so you can't just intercept the tab key.)
Now I come from a mobile first philosophy so I would say your markup should be mobile first. That means putting the modal outside of your <main> as discussed earlier.
This obviously causes a huge problem on a desktop. You now have the content sat somewhere it shouldn't be.
Because of this you only really have two options here.
Option 1
Use JavaScript to reposition the modal content in a predefined placeholder <div>.
So you keep your mobile first design, then use JavaScript to find the innerHTML of your modal and move it into the body within your holder. Then delete the modal itself just to be sure.
While you are at it I would also delete the button, just in case someone resizes the screen to a mobile view, we don't want a button leading nowhere.
Alternatively don't delete the second content then people can resize the browser, just means a few extra DOM nodes (so as long as your modal content isn't over 100 DOM elements I would say do this.)
If you decide to keep the modal make sure that is also display: none for the same reason as the button, we don't want people accidentally accessing it.
Option 2
Duplicate content.
I know, I know, duplicate content is just, urgh.
But sometimes you just have to put up with it if it is for the best.
By duplicating the content into a div from the start you do get a few advantages.
Advantages
If the user resizes the screen you can just use CSS to switch between views.
No need for JavaScript, great for if your site functions without JS or when your JavaScript fails.
Although it adds page weight it is likely to be better for performance overall, the potential for layout shifts with the first option resulting in a high Cumulative Layout Shift is quite high (although avoidable). With Google putting so much emphasis on Web Vitals I would start considering them now. Additionally you might find you write nearly as much JavaScript as there is HTML if your modal only contains a couple of elements.
Disadvantages
You would have extra page weight due to duplicated HTML.
You may have to adjust scripts etc. to account for the second duplicate item (although this should be minor).
This would still be my preference, Keep It Simple! This is far more robust
Option 3 (for the future)
Client Hints are one way you could solve this, turning responsive design into a hybrid of mobile vs desktop and responsive.
When client hints has enough of a market share you could simply use the header to decide which version of the page to send from the initial request.
You could possibly implement this today if you are willing for 25% of users to see the mobile version of your information on desktop, depends how important the info is.
Other considerations
There are a few other things to consider that you haven't mentioned so I thought I would add for reference.
I already mentioned adding aria-hidden to all elements outside of the modal when it is active.
To future proof your application use inert on items outside of the modal. Support isn't great (none existent!), but every little helps and it is quite likely to get implemented!
You can polyfill it if you want but I don't think it has moved outside of the draft spec yet so we just use it as is.
Also add aria-modal="true" to your modal.
I covered a lot of these points in a bit more detail in this answer if you want a bit more info.
Make sure you include <meta name="viewport" content="width=device-width, initial-scale=1.0"> in your <head> tag.Then in your style, you can play around with
#media only screen and (max-width:620px) {
/* For mobile phones: */
}
You can learn more about the #media rule here: W3Schools Media Rule.
If you have any more questions be sure to ask!
The accessibilitys properties are only aria-expanded="false" aria-controls="filter-panel" don't change it.
Your class and ID names doesn't have any impact on accessibility.
If you only want to show the content by default on large device, and display a call to action to show it only on smartphone device, you could do that with javascript and media-query.
We are running a tool called Axe to check the validity and 508-compliance/accessibility of HTML pages.
This error comes up as a violation:
Elements should not have tabindex greater than zero
The app is structured with top links and a nav bar. If we don't put in a tabindex, the tabbing starts from those elements. The idea is to hit the form inputs directly when coming onto the page. Surely that makes sense and should be allowed (even for disabled users)? Then why is a legitimate use case getting flagged?
<input id="phone" name="phone" tabindex="5" placeholder="" class="input-block-level" type="text" value="222">
Having a tabindex greater than zero is allowed in HTML in spite of what AXE is saying.
However, the way that you're using tabindex is presenting information to sighted users that is essentially being made unavailable to non-sighted users because they can't tab to it.
A better way to approach this would be to use hidden "skip links".
The idea is simple enough: provide a link at the top of the page which jumps the user down to an anchor or target at the beginning of the main content.
https://webaim.org/techniques/skipnav/
For sighted users, it's nice to have the focus on the first actionable element, such as the search field on amazon.com (although they don't do that). But sighted users have the whole page to take in with a quick glance. They can see where the focus is (assuming you have a focus indicator, 2.4.7) relative to the rest of the page and will immediately know there are navigation elements before the focus location and more stuff to interact with after the focus location.
For low vision users that use a magnifier, their viewport will be shifted to include the element that has focus. Usually when a page loads, the focus goes to the first element in the DOM that can receive focus. That's typically a "home" logo in the upper left (for LTR languages). Because the viewport is in the upper left, the low vision user will know that they can drag their viewport to the right or down to explore more of the page. But if the initial focus is somewhere in the middle of the page, that can be disorienting. The user might not know where on the page they are. How far from the upper left has the viewport shifted? How far can they explore up or down, left or right?
For extremely low vision or visually-impaired or blind users, users that use screen readers, the disorientation is even more dramatic. Screen reading software has great navigation tools so it's easy to explore the various elements of the page, provided semantic html elements are being used such as <h2> or <table> or <ul>. You can navigate to headings using the 'H' key, tables via the 'T' key, and lists via the 'L' key. But again, screen reader users will expect the initial focus to be in the upper left. They can certainly orient themselves and figure out where they are on the page, but it does take some cognitive effort, similar to the screen magnifier user.
So how do you make a pleasant experience for all these types of users (among many other types of users too)?
As one answer notes, "skip links" are very handy. In accessibility terms, these are called "bypass blocks" (2.4.1). They allow the default focus to be in the upper left (or wherever the default focus goes) and when you tab, the focus moves to the "skip link", which is an in-page link that lets you jump to the main part of the page. This is great for keyboard-only users (which might be sighted or visually-impaired users), screen magnifier users, and screen reader users.
However, if you really want the focus to be on a particular element, if the element is an <input> or <button> element, you can use the autofocus attribute. For other natively focusable elements, such as an <a>, you can have javascript that runs on load to call focus() on the element.
It's not a WCAG violoation to have the initial focus somewhere on the page other than the first element, so you're ok putting it on your form, just do it in a way to reduce confusion for users that have limited sight or can't use a mouse.
For more information about tabindex, see "5.5 Keyboard Navigation Between Components (The Tab Sequence)". Note that for tabindex values greater than 0, it says:
"Authors are strongly advised NOT to use these values."
I manage a lot of ads on a website. I want to make the ads accessible, and I've been been researching this but there is little information out there currently about how to make ads accessible. While I look into this further, I'd like to make them at least invisible to screenreaders, so that they are skipped over and ignored.
The ads are usually in the following format:
<div class="ad">
<iframe>
<html><body><div>Various more child divs here</div></body></html>
</iframe>
</div>
Is it appropriate to use aria-hidden="true" on the parent div? I was reading that would apply to all child divs, which is great, but also that it is intended for items that are not visible to anyone, not just those using screenreaders. But the ad is visible -- I just don't want screenreaders to bother with it.
Ideally I would also like to make it so that the entire ad element is not part of the tab order and can be skipped over, but tab-index="-1" does not apply to child divs like aria-hidden="true" does, and as such I would need to apply it to all the child divs, which is difficult. I'm not sure if there is a way around this.
So this comes down to three questions:
Can I use aria-hidden=true on the parent div?
Is there a way to use tab-index=-1 to make sure the entire ad element gets skipped over when tabbing?
Is there anything else I should consider?
yes, aria-hidden=true will prevent screenreaders to read that
you can apply the same method I indicated in How can restrict the tab key press only within the modal popup when its open? to disable keyboard interaction (which is very simple with jQuery UI)
Accessibility concerns a lot of people where blind people using screenreaders are a small part of them. So your adds won't become magically accessible by removing them to screenreaders or from keyboard navigation.
If you put ads on your website, then you suppose people will want to click or navigate to them. How can someone who navigate with keyboard click on your ads if you remove it from the tabindex? How someone with low vision will be able to read the content of your ads using a screenreader if you remove it from your accessibility tree? It's for that exact reason that aria-hidden should be used to match the visible state of the element.
There are much more people with low vision or using keyboard navigation than full blind people using screenreaders.
I am Trying to find out the "correct"(best practice) way of creating toggleable sidebar with bootstrap 4. Gone through the examples on the internet and not so sure if those were so good...so If someone can send me related resource links ,it would be great so that I can analyze it.
-I am from android platform so I'm a newbie when it comes to web development but I'm trying to achieve that kind of sidebar like on this side: link -notice: sidebar doesn't change its width(stretching) while changeing the size of a browser -until a point when it jumps over to icons width.
Bootstrap does not have an "official" sidebar implementation so nothing is "correct" here. As long as it works cross-browser/cross-device, anything is good to go.
Regarding the sidebar implementation itself, there are various options:
opens above the content,
pushes the content to the opposite side
squeezes the content
The above options and the array of animation possibilities for:
the sidebar itself,
the menu item containers,
the menu names/labels
and the menu icons...,
...make any attempt at providing an example prone to subjective preference and would render your question off-topic.
Other possible features are
auto-open above certain width,
auto-close below certain width,
reordering of elements,
three-state (full, min and off).
But on topic, the only objective answer to your question is: there is none (official).
As a starter, you might want to take a look at this simple sidebar. It works prefectly fine with v4. Just import the simple-sidebar.css and adjust the calls to match your project's elements.
In the end, the sidebar is all about two containers and applying a class (plus, ideally, some aria- attributes for screen readers). What you put in those containers and how you adjust the contents to look in each element state is all about your own (or the designer's, or the client's) personal preference.
I'm hoping to improve the experience for people using screen readers on a site that has a few menu levels with a lot of links (that might feel endless to people hearing every item).
Is there a way of instructing the screen reader what to say? Other than using a link and the SR reading the text (which in this case wouldn't make much sense). I was thinking something like:
"Further filtering of events can be done in the following sub menu. If you do not wish to do so, please tab through the sub menu to the event listings."
I know this isn't ideal; - at the moment I'm trying to figure out how to allocate focus to an element without javascript/jquery so that the tabbing through isn't necessary - but for future reference (for example if an element needs further explanation that isn't a link with text) this would be good to know.
I already have a Skip Navigation link on the page, but that is for the main menu.
Multiple skip links can be used
You could create a hidden link before the menu that allows you to skip it, if that's what you mean. When a user tabs onto it, they would hear your instruction and by selecting it they could bypass the menu.
More information on the WebAIM site: http://webaim.org/techniques/skipnav/
Highlights:
The idea is simple enough: provide a link at the top of the page which
jumps the user down to an anchor or target at the beginning of the
main content.
Probably the most accessible method for visually hiding skip links is
to hide them off screen, then cause them to be positioned on screen
when they receive keyboard focus.
Skip links or other in-page links can also be used to allow users to
jump to or jump over page content. For example, the Table of Contents
at the top of this page includes in-page links to facilitate
navigation to page areas. A "skip" link could also be used to allow
the user to quickly bypass confusing or potentially inaccessible
content, such as ASCII art, complex tables, etc.
The Open Ajax Alliance Accessibility Examples site might help: http://www.oaa-accessibility.org/example/25/
It is difficult to tell from your description whether this is applicable to your situation. If it is then the example site provides a great amount of implementation guidance for incorporating ARIA into your solution.