Update August 21st 2014: I’ve updated the skip-links section to add a fix for an issue in Internet Explorer and Chrome. This fix has been described in this “Fixing Skip to Content Links” article by Nicholas C. Zakas and so is not mine. Credit where credit is due :).
For my job at Highforge I regularly look at WordPress themes and other websites. More often than not I end up disappointed by the amount of themes that simply will not work properly when JavaScript is disabled, or don’t have a visual indicator for the :focus
state.
On the subject of JavaScript
The odds of a significant user-base with JavaScript disabled are currently pretty low, with even 97.6% of screenreader users (read more about this study, opens in a new window) reporting it enabled in a recent WebAIM survey (January 2014).
This, however, does not mean that the ideas behind Progressive Enhancement can be thrown out the window. JS can still fail for whatever reason. Maybe the CDN you’re using is having a stroke and you have no local fallback, maybe your visitor is behind a restrictive company or ISP proxy that mangles your lovingly crafted scripts, maybe (s)he is actually one of those people with it disabled (through NoScript or otherwise).
By being prepared for it, you can guarantee all your visitors will be able to access all the information on your website. Regardless of their JavaScript support.
Disclaimer: There are situations in which providing a fallback is ludicrous. If you’re absolutely sure your site or app falls into this category, then by all means, rely on JavaScript.
The wonderful :focus state
In case you’re not familiar with the :focus
, it’s a state that gets triggered when selecting a link by keyboard (using the tab key). Much like the :hover
state, it can be styled with CSS just as well.
Now imagine hovering over a link with your mouse and nothing happens. The mouse cursor doesn’t change, the link’s text doesn’t change. For all intents and purposes, the link doesn’t actually look like a link or seems like it’s functioning. In fact, let’s say the mouse cursor is completely invisible. This is essentially the equivalent of trying to browse a website without a visible :focus
state with a keyboard. Needlessly difficult.
A simple fix is to simply apply the :hover
style to :focus
as well and go from there. This is what I’ve done on this site as well (Go ahead, try it!). There’s two exceptions: the skip link, and the active menu item. Each of these have their own way of displaying they are, in fact, the link in focus.
title attribute
To put it brief, the title attribute is not meant to repeat whatever the anchor text is. This is something WordPress gets wrong too, because it’s a fairly simple way to do fill this attribute.
Ultimately, your goal is to make your links as descriptive as possible. Contrary to popular belief, the title attribute doesn’t get exposed to a majority of user agents and so you cannot rely on this to convey crucial information. If you really need to make a mostly non-descriptive link, make sure that it visually makes sense and use screen reader accessible text that’s visually hidden to further describe the link.
So what should you put in the title attribute? Here’s what the W3 has to say about this:
The title
attribute is used to provide additional information to help clarify or further describe the purpose of a link. If the supplementary information provided through the title
attribute is something the user should know before following the link, such as a warning, then it should be provided in the link text rather than in the title
attribute.
alt attribute
The purpose of the alt attribute is to provide a textual alternative for visual content. When you put an image into your page with an img
tag, screen readers will see this and read out whatever text is in the alt
attribute. The appropriate content for this attribute describes the image in such a way that someone without vision can still imagine the essential details of the image.
If the image is simply for decorative purposes, you really should consider using CSS and background-image
instead. This way, the flow of content isn’t interrupted by the irrelevance of a random image.
Skip links
Skip links are links all the way at the top of your markup. They are generally hidden, and will only be registered by screen readers. Their main purpose is to skip the droning of navigation while navigating through the website. Not giving your blind visitors the option to skip the navigation and go straight to the content will most likely make them leave your website, annoyed, because their screen reader just went through your navigation needlessly.
Adding one of these helpful functions is very simple. All you’ll need is an id on the content wrap so that you can link to it and then drop something like the following right after your body tag:
<a href="#content" title="Use this link to skip the header navigation">Skip to content</a>
Unfortunately, we must use JavaScript to fix this properly. The fix is two-fold: We need to set focus on the element we’re linking to and we need to set a temporary tab-index on elements that normally aren’t focusable (ie. just about everything but links, buttons, and inputs).
We’re using the hashchange
event so that our script triggers every time an in-page link is clicked.
window.addEventListener("hashchange", function(event) { var element = document.getElementById(location.hash.substring(1)); if (element) { if (!/^(?:a|select|input|button|textarea)$/i.test(element.tagName)) { element.tabIndex = -1; } element.focus(); } }, false);
Final thoughts
The best way to find blatant flaws is to simply try it. Try navigating your website with just your keyboard and see where you get stuck. Try using a screen reader like ChromeVox, a screen reader extension for Chrome, close your eyes, and see what that’s like. I can guarantee that it will change the way you think about how you are building websites.
Do you have any other quick tips? Am I wrong on the internets somewhere? Let me know! Fill out my contact form.