I am working on a web page where user has to scroll a lot.
For ease of use, I have added the back-to-top link at the bottom of the page, so user can navigate to the top of the page.
Now I have a html markup like this:
<a class="btn-primary" href="#top">
<span class="btn-content link-content">
<svg focusable="false"><use xlink:href="#arrow-upward"></use></svg>
</span>
</a>
How can I make my link more accessible? I have thought of adding aria-label, but other than that nothing crosses my mind
First of all, render your component usable, for example by following NNg’s Back-to-Top Button Design Guidelines. This is a solid basis. Thanks to #outis for the hint.
Here are some accessibility concerns that come to mind with regards to such a Back to top component.
Alternative text/accessible name
Every interactive element needs an accessible name. This text is not only what gets read by a screen reader when focussing the element, but also how voice control can identify the button, as in “Click on back to top”.
Accompanying text for sighted users
Adding a tooltip for sighted users via the title attribute is always a good idea as well, but you should never rely on that attribute to provide an accessible name, as implementation in screen readers is not good.
Even better would be having the text always visible for everyone. Not everyone gets icons correctly.
That way you also provide a very visible hint to voice command users.
The visible part needs to be included in the accessible name (alt text) for this reason. You should add role="presentation" to the SVG if you have accessible text next to it.
This is an example from the GOV.UK Design System Guidelines, who care a great deal about accessibility. They add it just before the footer on long pages.
Contrast
Since you didn’t share your CSS, we don’t know what it does with colours. You need to make sure that the icon and text’s contrast with the background are still 4.5:1 or above.
Avoid icon-fonts
You already got that right. (:
Since users with reading disorders often make their browser use a font they can read well, icon-fonts will break and remove icons that—ironically—would help them most.
Be careful with animated scroll
Often developers (or designers?) like to fly back to the top instead of the instant jump. This can help users orientate.
Nowadays we can simply specify this with scroll-behaviour: smooth and let the browser do the work.
However you implement this, you should be careful to not cause vertigo in people who are sensitive to these zoom animations. Only apply this if the user can and did not set prefers-reduced-motion
Focus
While it is important to include the button in the tab order, it should probably come right before the footer, even when it’s visible all the time.
Focus needs to be visible, of course, as for all interactive elements.
Keyboard users can easily jump back to top by using their Home key, so it’s less important to have the button in early in focus order or after each chapter or something.
When the button disappears when arriving on top, focus needs to be put somewhere else, it must not be “lost” (going to body or html).
Refer to the WCAG
I might have missed some criteria in this answer.
If you want to be sure, you can open up the WCAG-EM Report Tool and start creating a report for your component.
All criteria of the Web Content Accessibility Criteria will need to be audited by you. This is the industry standard for accessible web applications, and legally binding in a lot of states.
You can also add the Title attribute in your anchor tag
<a class="btn-primary" href="#top" title="go to top of page">
When working on the in-page navigation links, we should not forget the screen reader users, so we must ensure they know the purpose of the link. A common way is an aria-label attribute specifying a meaningful value, such as 'Go to top' or 'Back to top'. Once the aria-label is specified, the content of the link should be hidden from the screen reader (Exceptions exist) i.e.: via aria-hidden='true' .
Another detail that should not be forgotten is the focus handling. By default, most of the browsers just scroll the page when using an #Element's_ID for the href if the id does not exist, and SR/Keyboard users will be affected in such a way that after the page is scrolled to top and Tab key is pressed the focus will move to the next focusable element before the page was scrolled up, so, the result will be, an undesired page scroll down.
There is a working implementation in W3C patterns page https://www.w3.org/WAI/ARIA/apg/patterns/.
Hope this helps in your accessibility journey. The a11y world needs lot of people interested on it.
<body id="top">
...
<a class="btn-primary" aria-label="Back to top" href="#top">...
</a>
...
</body>
Related
I'm very new to React and Javascript, but hoping someone might be able to offer thoughts regarding how to reliably switch keyboard focus on a route change. In the following, selecting any of the menu items(green box is an example) on the LHS leads to a change in the main screen(orange box), but keyboard focus remains on the LHS after pressing Enter.
What I'm trying to achieve is that the keyboard focus switches to being the text highlighted(blue box), thus giving a better experience from a usability point of view. Having searched google, I believe to command to achieve this to be one of the following:
document.getElementById('content-container').focus();
document.getElementById('reviews-in-progress-title').focus();
with the stated Ids being those from the blue boxes in the debug tools. They represent the main screen and specific element, respectively however, neither achieves the desired effect.
What I am able to achieve is switching focus to the element highlighted in the red box using the following:
document.getElementById('sortable-column-manuscriptTitle').focus();
So, my question for the floor is: why is it that I'm able to switch focus to the red box, but not the blue one? It feels like this will be a pretty common (and solved/understood) problem, but I'm not currently able to crack it. Any input gratefully received.
Thanks,
Phil
Some browsers won't allow the focus to be moved to an element if it's not an interactive element. In the blue box, you have an <h1>, which is not natively focusable. In the red box, you have a <buton>, which is focusable.
To get around it, add tabindex="-1" to the <h1>.
This will allow the focus to be moved to a non-interactive element via JS but won't allow the user to tab to it.
Now, having said that, in general you should not move the user's focus unless there's a really good reason for it. You mentioned you wanted to do it for a
"better experience from a usability point of view"
As a keyboard only user, I would find that a worse experience. If I'm a new user to the app and I wanted to explore the LHS menu to see what's available, I would tab to the menu, press enter or space to select the menu, then see what appears on the right. I'd then want to tab to the next menu item and select it to see what appears, but you moved my focus over to the right so now I have to shift+tab all the way back up to the menu. If I were using a sip-and-puff device or another assistive technology instead of a keyboard, that's going to be a lot of effort.
So your intention is good but it might cause a lot of difficulty for some users. That's why I recommend not moving the user's focus unless there's a really, really good reason for it.
Of course the opposite argument can be made. If the focus is not moved then the sip-and-puff user will have to navigate all the way over to the right side to interact with what appears.
You have to do some research to see what might benefit the most users without adversely affecting other users.
I'm mainly interested in the a11y aspects
So as you might be aware, sometimes you might wish to have a button that acts as an anchor.
These are 4 ways (I can think of) of approaching this issue:
1. Button inside an anchor element
<button>Button</button>
2. Anchor inside button element
<button>Button</button>
<!-- Also should it be a href or button onclick (?) -->
3. Anchor styled as a button (without a button element)
<a class="buttonLike" href="//redirection">Button</a>
4. Button acting as a redirection (without an anchor element):
const button = document.getElementById('button')
button.addEventListener('click', () => {
window.location.href = "//redirection"
})
<button id="button">Button</button>
I've tried to find an answer to this myself. Closest I could find was this excerpt:
According to the MDN anchor spec, which states the following:
Anchor elements are often abused as fake buttons by setting their href to # or javascript:void(0) to prevent the page from refreshing, then listening for their click events .
These bogus href values cause unexpected behavior when copying/dragging links, opening links in a new tab/window, bookmarking, or when JavaScript is loading, errors, or is disabled. They also convey incorrect semantics to assistive technologies, like screen readers.
Use a <button> instead. In general, you should only use a hyperlink for navigation to a real URL.
Unfortunately this doesn't help me too much. Basically all it states is you should not use the third approach (anchor styled as a button) if you don't mean to provide a real link to it, which is not what this question is about.
Is there any official WCAG on this subject matter that I was unable to find or?
Option 1 is not valid HTML.
Option 2 is not valid HTML.
Option 3 is the correct choice here.
Option 4 is semantically incorrect.
Semantics are one of if not the most important aspects of accessibility.
There are two things at play which dictate option 3.
The first is that an anchor should be used only to jump to sections and to navigate between pages.
The second is that a button should perform actions on the same page.
Now if you want to style a call to action link to look like a button that is fine but make sure you use the correct semantics, but make sure that CTA leads to a new page or it isn't semantically correct.
And although it is swearing on StackOverflow to mention SEO, a hyperlink rather than a JavaScript redirection will be far better.
The first and second rules of ARIA say:
1st rule : If you can use a native HTML element [...] then do so
2nd rule : Do not change native semantics, unless you really have to.
Interactive elements like a and button can't contain other interactive elements:
The a element may be wrapped around entire paragraphs, lists, tables, and so forth, even entire sections, so long as there is no interactive content within (e.g. buttons or other links).
So, as what you want to do is linking to a page, your third solution is obviously the only one correct.
I think you might have confused the "bogus" stagement which refers to your 4th example.
From my little experience with Accessibility and semantics there is no "one size fits all". It really depends on your priorities and the user experience you are aiming for.
A <button> gets all the accessibility goodies from the browser automatically: Being selected or pressed using the tab or spacebar/enter keys.
A <a> element is a link, links are meant to be used as links or anchors within a page.
Anchors are not as important in comparison to a button within a page. From a user experience point of view; a button is used by people to interact with a UI, either to confirm or make the UI do something. Pressing a button provides a different feedback compared to a link. Anchor links on the other hand help a user with finding content within a page.
Again, it really depends on what you are trying to do:
Is this a terms page or an article? Then list your anchor links without any button-like styling
Does this a link that has to look as a button so users find it easier to spot or interact? Then style it as a button without it being actually a <button>.
Say there is piece of text (regardless of whether it is styled as a "traditional" link or button) on a page that when clicked leads to a new page with a new page/URL. But the navigation happens programmatically (e.g. via react-router using the History web API) instead of a hard HTTP refresh.
In this case, should it be a traditional anchor link with href attribute such as # or a button?
Option 1:
<a href="#" onClick={navigateToNextPage}>Link</a>
The downside is that you have a junk href attribute. You could remove that but then it is not in the tab order and doesn't get default link styling (though these could be overcome with one-off styling). Also if you copy the link it will copy as # which is incorrect and be interpreted incorrectly by screen readers.
Option 2:
<button onClick={navigateToNextPage}>Link</a>
The downside here is that if you want it to look like a traditional link you need to apply custom styling. Also in some ways it is really acting like a traditional link in my view. But this would be better for screen readers.
I can't comment on React but here is the correct method for SPAs, implementing it should be trivial in React.
Short Answer
Use a hyperlink (<a>) to navigate between pages and when loading additional content if no other option is available.
More simply: if the URL changes or you add large amounts of information to the page, use a hyperlink.
Long Answer
In your question you mentioned the History API and react-router.
For this reason I assume that the function navigateToNextPage changes the URL.
I also assume that I could access that page directly if I desired by entering that URL into my browser.
With those assumptions in mind you should use:-
<a href="new-page-url" onClick={navigateToNextPage}>Link</a>
Obviously you would stop the default action (e.preventDefault() or React equivalent).
A couple of points on why to use the format described above:-
Accessibility - when I encounter a hyperlink with a screen reader I am able to ask my screen reader where that link will take me, this is reassuring, I can't do the same with a button. This is why I didn't use # for the hyperlink but instead added the actual destination. If you see href="#" it is nearly always a sign that the wrong element is being used or it is being used incorrectly. After reading your comments about performing an action before navigating this is still perfectly valid, perform your action and then redirect, it is still navigation at the end of the day.
Accessibility - when I am navigating a site via a screen reader I may decide to cycle through all the hyperlinks on the page to get a feeling for the page structure. (NVDA modifier + K to get next link for example). I am very unlikely to loop through all the buttons on a page to look for navigation.
Accessibility - If I encounter a link I expect the page to change (even via AJAX). If I encounter a button I expect it to perform an action on the current page. Expected behaviour is a key part of accessibility.
Accessibility - hyperlinks have some important states. 'visited' is a key one on pages with lots of links as I may want to review something I read earlier and being able to navigate via visited links (e.g. NVDA modifier + K for all unvisited links). Buttons do not expose this information. An important point here is that you also can't style a button with button:visited in your CSS so you miss out on the visual clue for everybody there.
Accessibility - Space key vs the Enter key. If I land on a link I am expecting to press space to navigate, a <button> only works with the Enter key and so I may be confused as to why the page isn't changing. (I am assuming at this point you have used a load of aria to convince me this button is a hyperlink).
Robustness - If your site has limited functionality when JavaScript fails a hyperlink is far better than a button. It will still work when JavaScript fails and this is especially useful when a JavaScript failure may only be a temporary load problem with one page, allowing a user to get to another functioning page.
SEO - I dare to speak of SEO on Stack Overflow? Shame! Shame! Shame! :-P - but seriously although Google is pretty darned smart in what it can do on JS powered sites it does still struggle to work out where a JavaScript only link will take it. If SEO matters for you then use a hyperlink with a valid destination so Google can map information correctly.
Probably other reasons I have forgotten to mention but I think I have made the point.
What do you have to consider when using AJAX to navigate between pages?
Although not part of your question I thought I would quickly add a couple of points for completeness.
You need to signal to a user that a page is loading if you are using a SPA pattern (and therefore interrupting normal navigation). e.g. I click your link you need to let me know that an action is being performed (loading.....) as you intercept the normal browser behaviour with e.preventDefault() or equivalent.
The simplest way is to use aria-live=assertive on a region that explains the page is loading. You can Google how to implement that correctly.
Additionally when the new page loads you need to manage focus.
The best way to do this is to add a level 1 heading (<h1>) to each page that has tabindex="-1".
Once the page loads the last action you perform in your JavaScript navigation function is to place the focus onto this heading.
This has two benefits:
it lets the user know where they are now
it also lets them know when the page load is complete (as AJAX navigation doesn't announce when the page is loaded in most screen readers).
By using tabindex="-1" it means that the heading won't be focusable by anything other than your JavaScript so won't interfere with the normal document flow.
You can just do e.preventDefault() when clicked on <NavLink> do your thing. Then navigate. NavLink generates <a> tag in HTML and provide active class by default when route is active. This allow you to style active state link.
import React from "react";
import { NavLink, withRouter } from "react-router-dom";
function Header(props) {
const handleClick = e => {
e.preventDefault();
console.log("DO SOMETHING");
props.history.push(e.target.pathname);
};
return (
<ul>
<li>
<NavLink exact to="/" onClick={handleClick}>
Home
</NavLink>
</li>
<li>
<NavLink to="/about" onClick={handleClick}>
About
</NavLink>
</li>
<li>
<NavLink to="/topics" onClick={handleClick}>
NavLink
</NavLink>
</li>
</ul>
);
}
export const HeaderNav = withRouter(Header);
Wokring example: https://codesandbox.io/s/react-router-5-rqzqq
I would recommend you to use semantic HTML. This means using the correct HTML elements for their intended purpose as much as possible.
Easier to develop with — you can get some functionality for free, plus it is arguably easier to understand.
Better on mobile — semantic HTML is arguably lighter in file size than non-semantic spaghetti code, and easier to make responsive.
Good for SEO — search engines give more importance to keywords inside headings, links, etc., than keywords included in non-semantic
s, etc., so your documents will be more findable by customers.
There's more details
I'm trying to figure out a way of clicking an Anchor link TEMPLATES
on the top of my page without having the browser scroll to the point of my anchor.
Sounds redundant huh?
Wait.
My anchor link is inside of a overflow: Hidden text box where clicking the Anchor link
at the top of my page should only raise the anchor in the Overflow text box displaying it's
content, like having a new webpage. From a layout perspective the browser must always be at the top of the page where my form is.
Anyone have a clue?
Thanks
UPDATE:::
Oh spoke to soon, looks like the Css and Javascript - Show and Hide method would be more adequate.
Found here: http://webdesign.about.com/od/dhtml/a/aa101507.htm
Thank internet!
It is very easy do so. What you are trying to do is to have a parent div/view which would act as the main div and all the other divs/views will be loaded or unloaded within it dynamically or so as its children. It would better to employ a design pattern such as "MVC", but it can be done via JQuery straight up. If I was to tackle something like this, I would have a "navigation view" and then content views so when a user clicks on the desired navigation link, that particular view will be loaded or scrolled in. (Of course, you need to experiment and line your depths as desired for the content views).
This is how Flash is programmed. This is a very high level explanation, and I hope it gives you somewhat of an idea about getting it going.
I'm using a poshytip, it is working fine, until I want to display my tip on the element that is under the current page (I mean that page where I have to scroll down to see it, don't really know how to name it properly). Unfortunately, poshytip has some bugs related to that - if I want to display a tip on the element that is currently lower than the current page position, then tip is showing at the bottom of my page. Havent seen any better tip plugin than this, so I decided to fix it on my own.
The question is - is there a way in jQuery/javascript to check if the element (for example the input with ID) is on the current page that user is viewing? By saying current page I mean the top of the page - my element is placed much lower, so user have to scroll down the page to see it, so is there a way to do something like: if user is scrolling down the page, and the element will be finally visible then send alert to the user?
I know this may be kinda complicated, but couldn't find any better words to describe my problem, I'd answer additional questions, if you have one.
If you want to test for an element's visibility in the viewport, you should reference this post here as it's outlined quite clearly.
On another note, I prefer using the jQuery tools suite for my Tooltip plugin of choice. You can see it here