There are some things in the world of accessibility that appear, on the face of it, to be really wonderful ideas… until you scratch slightly below the service. What may seem feasible when putting together some guidelines on accessibility might not ultimately translate well to a real-world application. Hands up who can remember the last time they felt compelled to use a longdesc attribute? And what about the accesskey attribute? Oh, you have used them you say. OK, let’s back up a little and find out what went wrong here.
The Problem With Accesskeys
The accesskey attribute is a neat little feature that is supposed to enable the user to quickly access a navigation, search, or some other feature of a page quickly. For example, I could use an accesskey of ’s’ for search on a site - on all sites that I might run - and have that as the trigger. Depending on the browser or other assistive technology (AT) used, that might involve the user hitting CTRL+s to activate it, or maybe ALT+S, or perhaps some other configuration.
However, those very same commands might be the same as existing commands in the browser or AT. So which command takes precedence? There is another factor to this ‘key already assigned’ problem, and that’s one of localization. While you may think that your browser has a spare key that you could use, in many other languages this won’t be the case.
Another problem with the accesskey attribute is how do you let the user know about it? As with the longdesc attribute, the availability of the attribute is not really shouted from the rooftops (with the exception of the little-used iCab browser). Unless you make a point of informing the user of accesskeys being used on the site in a separate page, perhaps backed up by judicious use of the title attribute for the relevant links, the user may never know that you made them available.
So it seems that, while accesskeys are a great idea, they are largely hidden and also cause their own set of problems because of the potential overlap with other technology. But wait, maybe there’s life in the old dog just yet…
Let the User Decide
I have an idea, or rather I had an idea, about the way it might work. I actually used this approach a couple of years ago when I re-built accessify.com, providing a method for the user to set their own accesskeys. They are not forced upon anyone - it’s a total opt-in. But in all honesty, it was more of an experiment on a live site than anything else, and it’s not transferable to other sites unfortunately. The solution was built using PHP, but I always thought that it could be converted to a JavaScript solution. It just took me a couple of years to get around to it (and documenting it!).
The JavaScript Approach
In the JavaScript solution, the end result is exactly the same as the version used on Accessify, just the mechanics have changed. Rather than go into all the lines of code and explain everything line-by-line, I’ll summarise how it works in plain old English.
- There are a number of links on the example page (the links that we offer up as potential accesskey candidates) By default, they have no
accesskeyassigned, nor anytitleattribute:
<h3>Navigation</h3>
<ul>
<li><a href="/" id="homelink">Home</a></li>
<li><a href="/search/" id="searchlink">Search</a></li>
…
</ul> - There’s a warning on the page that says "you need Javascript to set your own accesskeys" - this is set to display on screen by default
Finally, there’s a form that allows you to set the characters you want for the related sections on the page. This is hidden by default (using CSS)
<p id="warning">Cookies are used to save these preferences, but you have either disabled JavaScript, set your browser not to accept cookies, or your browser supports neither. The site will work perfectly well without these preference options.</p>#warning
{
color:red;
}function hideWarning()
{
var elwarn = document.getElementById(’warning’);
elwarn.style.display="none";
var elsetter = document.getElementById(’setter’);
elsetter.style.display="block";
}
If the user gets to the page with JavaScript disabled (or with the scripts not properly downloaded - perhaps blocked by a firewall), they will essentially get the default page that says "You can’t do this, you need JavaScript to set this stuff" and no facility to set it is displayed.
If JavaScript is available, though, it’s a slightly different scenario:
- The warning message that’s set to display by default gets suppressed (after page load, by having the CSS
displayproperty set tonone) - The form that accepts the user’s desired
accesskeyassignments is made visible (again, using JavaScript to change the CSSdisplayproperty)
Now that we know that the user has JavaScript enabled and was able to get all the source files correctly, they can then go ahead and save their accesskeys.
Saving the Accesskey Choices
The process of saving the choices made by the user are fairly standard JavaScript/cookie methods - one long string is saved that has a number of property:value pairings (one for each link or button that can potentially be assigned an acccesskey). For example:
<form action="set-access-keys.htm" method="post" name="frmAccessKeys">
<fieldset>
<legend>Set Accesskeys for … </legend>
<div>
<label for="txthomelink">Home link</label>
<input value="" name="txthomelink" id="txthomelink" type="text" size="2" maxlength="1" />
</div>
<div>
<label for="txtsearchlink">Search Box</label>
<input value="" name="txtsearchlink" id="txtsearchlink" type="text" size="2" maxlength="1" />
</div>
...
</fieldset>
</form>
strKeyVals += "homelink=" + document.forms['frmAccessKeys'].txthomelink.value + "@@";
strKeyVals += "searchlink=" + document.forms[’frmAccessKeys’].txtsearchlink.value + "@@";
The @@ is simply there to make it easier to identify where to split the string when retrieving the data from the saved cookie later.
We also provide an option for the user to get a hint of the accesskey for each link or button with the use of a simple checkbox:
<div>
<input type="checkbox" name="chkshowhint" id="chkshowhint" />
<label for="chkshowhint" class="check">Show accesskeys in links and buttons (displayed after link in brackets)</label>
</div>
strKeyVals += "showhint=" + document.forms['frmAccessKeys'].chkshowhint.checked + "@@";
The process for capturing the information is initiated by an onclick event attached to the submit button, which passes it through to an addevent function:
addEvent(document.getElementById('cmdSubmit'), 'click', accessKeySetter, false);
(The function accessKeySetter is where the JavaScript code snippets above appear)
Remembering the Choices and Updating the Display on Page
Assuming the user has entered some values and also chosen to have the accesskeys showing in the links or buttons, once the page has reloaded following the submit, this is where the DOM really takes over.
Remember, we start with a page that has a number of links that have neither default accesskey or title attributes present, then we use JavaScript to present the option to manipulate/store accesskeys (if JavaScript is not available for whatever reason, the default page display is to warn them that they can’t do this and need to get their JS in order, or words to that effect). So, already, we’re using JavaScript in a nice progressive enhancing kinda way. The final stage is to use JavaScript and the DOM to update the page display depending on what’s found in the cookie. The steps to do this are as follows:
- Firstly, look for the presence of the
accesskeycookie - Assuming it’s found, take the content of that string and split it up into the individual links/buttons that it repesents (separated by the
@@characters that were shown earlier
//get the cookie
var strAccessKeys = readCookie("accesskeys");
//split up the values
var arrAccesskeys = strAccessKeys.split("@@"); - Then, each value found is split between the
idof the link or button it represents and the value stored against each (theaccesskeythe user wants to assign)
for (i=0;i<(arrAccesskeys.length-2);i++)
{
var thisAccessKey = arrAccesskeys[i].split("=");
var accessKayEl = thisAccessKey[0];
var accessKayAttrib = thisAccessKey[1];
… - Then it’s a case of running through the array of
ids in the cookie that have values assigned and matching them up to theids of elements on the page and then:- adding the accesskey value to the element
if (accessKayAttrib.length>0)
{
//set the attribute
document.getElementById(accessKayEl).setAttribute(’accesskey’, accessKayAttrib); - and updating the content of link or value of the button text to display the accesskey (if the user has requested this), and adding a title attribute too:
if (document.getElementById(accessKayEl).tagName=="A")
{
var strLinkPhrase = document.getElementById(accessKayEl).childNodes[0].nodeValue;
}
if ((document.getElementById(accessKayEl).tagName=="INPUT") && ((document.getElementById(accessKayEl).type=="submit")||
(document.getElementById(accessKayEl).type=="button")))
{
var strLinkPhrase = document.getElementById(accessKayEl).value;
}
document.getElementById(accessKayEl).setAttribute(’title’, strLinkPhrase + ‘, access key = ‘ + accessKayAttrib);
//display the accesskey hint, if that’s been chosen
if (blnShowHints)
{
strLinkPhrase = strLinkPhrase + " [" + accessKayAttrib + "]";
if (document.getElementById(accessKayEl).tagName=="A")
{
document.getElementById(accessKayEl).childNodes[0].nodeValue = strLinkPhrase;
}
if (document.getElementById(accessKayEl).tagName=="INPUT")
{
document.getElementById(accessKayEl).value = strLinkPhrase;
}
- adding the accesskey value to the element
- One final step, while traversing through the page, is to add the value chosen in to the form fields too, so they’re remembered, likewise the state of the checkbox.
The final result is a completely unobtrusive method for setting and remembering accesskey attributes which doesn’t enforce itself on the user - it’s completely opt-in.
[download the zipped version with all files required here.]
Possible Improvements
The biggest improvement that could happen with this script is to have it centralized somewhere, or some variant thereof, so that it could be re-used in some way. My thinking was that if this mechanism were possible to re-use across sites, then a user could potentially save some accesskey choices that would be usable for a number of different sites, but then there’s one fatal flaw in this idea - a cookie can only be read back by the same domain, thus if I were to set my choice for site whateverxyz.com, when I try to do the same for abcwhatever.com, it won’t be able to read back the same data. So I’m definitely open to suggestions as to how that might be made possible at some time in the future.
Outside Reading
This isn’t the first time someone has come up with a method for dealing with this, so here are a few other takes on how to solve the issue:
And if you want to to learn more about the background to the problem, here are a couple of recommended reads:
- Dave Shea: Keyboards and Chaos
- Derek Featherstone: Accesskey Conflicts




[…] Javascript ve DOM ile Accesskey’ler atamak ve düzenlemeyi anlatan İngilizce bir makale. Link […]
[…] Setting and Retrieving Accesskeys with JavaScript and DOM The final result is a completely unobtrusive method for setting and remembering accesskey attributes which doesn’t enforce itself on the user - it’s completely opt-in. (tags: Accessibility) […]
A fantastic technique… I currently allow my users to set the access keys using server side code, however you are absolutely right, why should this be pushed onto the user!
A couple of little improvements, just me being picky really… try not to use the document.forms[] array, its an IE thing (non-standard), the alternative is to use something a little longer, but more forgiving, like…
———————–
formRef = document.getElementById(’myForm’);
if (formRef) {
var inputs = formRef.getElementsByTagName(’input’);
for (var i = (inputs.length - 1); i >= 0; i–) {
inputs[i]…
}
}
———————–
Which leads me onto the second point… you cannot trust that getElementById will always be successful. Like in the above example, try to get a reference and then test to see if it was successful.
Thanks Craig. I knew that there would be improvements to this, and that’s exactly what I was looking for. Oh and the document.forms thing … old habits die hard but to be honest I’ve not read that referring to form elements in that way fails in any browser, but I suppose if that’s the case now it may not always be. So, thanks for pointing that out.
It has been time for some improvement in the usage of access keys. There’s a lot of work to do before this technology will be available to all the website visitors outside our castle. This technique is just one of many puzzle items that have to be sticked together. I expect this topic to be very useful in near future. Maybe it’s up to start some real introducting in accesskeys for everyone out there - marketing the accesskeys.
How do you think can we introduce this to joe public? When will this reach most of the web users?
Best regards from Germany,
Stefan
There’s currently nothing in that code that would prevent a user from assigning the same accesskey to multiple links. So perhaps one area for improvement would be to add a check to see if the character was already in use.
Just to set something straight: the forms collection as property of Document is in fact not IE-propriety but defined in the DOM level 1 standard, see: http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-html.html#ID-1006298752
Nice technique but who, realistically, is going to spend the time to customise a website with their own accesskeys unless?
@Craig, do you have any stats for usage of the accesskey feature on your site?
Hi Ian,
I like that you’ve spent the time to think this through but I’m not sure that the technology used is 100% appropriate (Javascript). I’m not fully clued on all the different blind browsers out there but I know there are certainly a handful that don’t run JS (by default at least), and for those people that I presume to need accesskeys more than anyone else I think this solution misses the mark some how.
This isn’t a dig, I know there are plenty of other disabilities which this could aid, such as difficulty in movement, etc. as well as people without disability who just like to surf smarter.
So perhaps you could run your server-side solution alongside this maybe? Just an observation.
Ian. Aside from accessibility (which I know is your primary driver) this technique has potential for enhancing standard web browsing.
I can imagine sites where users pick their preferred content / action and recall it without *clicking*. Think ebay (or any other big and sprawling site) enhanced with preference led keyboard recall.
Speaking of preferences - how about a style or preferences switcher controlled by these ‘custom keys’ of yours? That WOULD be interesting.
Thanks.
Does anyone else think the layout of accessify.com is lacking?
Joe, I appreciate people commenting here and I’ll answer questions raised, but really - just how is your question relevent?
Accessify has a CSS layout and it’s quite simple, admittedly. I’ve always felt that it was not a major requirement for it to be a design showcase. It’s functional and adaptable (but if you want to change the style there are some alternative options in the preferences section.
The design - or perceived lack thereof - has nothing to do with the topic at hand, namely how useful accesskeys are and how you might choose to implement them
@Mike - You’re right, some people have JS turned off which then means this solution fails. However, the key thing is that the JavaScript is all unobtrusive and progressive. In other words, it doesn’t ‘break’ when JS is disabled, you just get the normal document. If JS is enabled, it’s a bonus feature, not an absolute requirement. Does that make sense?
@Peter - You’re also right, there’s no checking for multiple accesskey assignments but it would be a good idea to add something in there to that effect.
Thanks for the reply Ian, how about as an addition, the possibility of pre-assigning the accesskey’s as you would normally, taking into account of what you were saying about problems, and then using your technique to replace those accesskey’s with the user’s preferred choice. Should JS be turned on, there’s still some level of use for some people.
.. Should JS be turned *off*…
Accesskeys = make sense?
A study of a german University tell something like this about Accesskeys:
First, persons with disabilites must lern for each site the accesskeys. Next, browser have their own keys to activate accesskeys. Here some samples:
IE = ALT + accesskey + Enter
Mozilla = ALT + accesskey
Opera = Shift + Esc + Accesskey
On Mac OS the most used key is the “Command” key
The browser developers make their own goal, there are no standards. Have people with disabilites really advantages by using accesskeys? And what about screenreader users? I think, it makes no sense to use accesskeys. Better is make a easy and clean site.
@Mike Holloway
I find accesskeys most useful for people with movement difficulty, not so much blind people.
I’m not disabled and even I prefer using accesskeys, especially one sites with long lists of search results where I’ll be pressing ‘Next’ for hours on end while searching for something.
I was so happy when istockphoto added accesskeys!
I’ve been trying recently to write a greasemonkey script that adds accesskeys to pages on pbase.com but haven’t gotten it to work yet (I suck at JS).
I think there should be a feature in all browsers that reads link tags in the head of the page and constructs a ’site wide’ navigation menu into the gui of the browser itself to represent the major links of a site. That way the screen readers can speak directly to the browser and get that info and help disabled people better instead of trying to read the links on the page itself.
@Matthias Mauch
I’m a non disabled user who uses accesskeys quite often.
@Ian Lloyd:
For centralizing the script how about when a visitor writes the cookie, simultaneously send an xmlhttp request to another site that saves that info in a database along with some sort of info to match that visitor to that info (a username/password saved in a firefox extension). Then when they visit a different site, try to figure out from the browser/extension who that person is and try to load their preferred values via xmlhttprequest from the central site.
[…] Setting & Retrieving Accesskeys with JavaScript and DOM Accessibility expert Ian Lloyd revisits the accesskey attribute, working with JavaScript and the DOM to enable users to set their own access keys. […]
Nice technique Ian.
But I am not sure how many of the users will really customize the access keys. Would you mind sharing some statistics if you have any?
I have one thing to add here, at least all blogs should follow some kind of predefined access keys for Home, Search, About Us and most commonly found features amongst all the blogs.
Chandra, I have no statistics to share with you, and if I did I probably wouldn’t trust them ;-)
As for your second point, well, that is the problem at the moment - any convention that is used will only work for some users, as mentioned earlier on in this article:
Hence the reason for suggesting that the user could set their own. Now, if such a system could work across a range of sites, that would be really useful
[…] Setting & Retrieving Accesskeys with JavaScript and DOM Accessibility expert Ian Lloyd revisits the accesskey attribute, working with JavaScript and the DOM to enable users to set their own access keys. […]
thnks for article
Very nice technique! But I think a lot of people have no time to customize the access keys.
yes but getting access key is very very hard
Wow, this is good
thanks editors
thank you. great job.
thank you great job
yes but getting access key is very very hard
thank you. great job.