2004-03-18

アクセスキーの示し方について考える

アクセスキーとは?

HTMLやXHTMLでは、accesskey属性を指定することでアクセスキーを割り当てることができます。割り当てられたアクセスキーの呼び出し方法はシステムに依存しますが、例えば、Windows用のMSIEならaltキーとaccesskey属性値を押すことでアクセスキーを利用することができます。

しかし、アクセスキーのレンダリング方法はUAに依存し、例えば、Macintosh用のiCabならaccesskey属性を持つある要素の先頭に割り当て文字を小さく表示することができますが、現状では、多くのUAはアクセスキーをレンダリングすることができません。

アクセスキーを本文に直接記述する。

アクセスキーの割り当てがある要素の前か後にアクセスキーを示したら良さそうですが、次のような場合だと不自然に感じます。

次の例では、a要素にアクセスキーが割り当ててある。当該要素の前の文字は、割り当てられたアクセスキーを表している。

<p>
 [<kbd>S</kbd>]
 <a rel="start" href="/" accesskey="S">らいおさむのお屋敷</a>
 について、より詳しくは、
 [<kbd>H</kbd>]
 <a rel="help" href="/help/" accesskey="H">ご案内</a>
 をご覧下さい。
</p>

上記の例は、次のようにレタリングされるので、文章として不自然なものであろう。

[S] らいおさむのお屋敷 について、より詳しくは、[H] ご案内をご覧下さい。

次の例では、当該要素に割り当てられたアクセスキーを示すと共に、文章としての不自然さを解消している。

<p>
 <a rel="start" href="/" accesskey="H">らいおさむのお屋敷</a>
 (アクセスキーは[<kbd>S</kbd>]です)
 について、
···

上記の例は、次のようにレタリングされる。

らいおさむのお屋敷(アクセスキーは[S]です)について、···

これでも文章としての不自然さを感じるのであれば、アクセスキーを示す記述をspan要素で包括し、CSSに媒体によっては隠滅したり、キー文字だけを表示させるという方法も良いかも知れません。

CSS2の疑似クラスでアクセスキーを表示する。

前節以外にも、割り当てられたアクセスキーのレンダリング方法として、次のような方法もあります。

次の例では、CSS2の疑似クラスを利用することでアクセスキーを表示することができる。

/* アクセスキーを表示する */
[accesskey]:before {
 content: "<" attr(accesskey) ">";
 font-size: x-small;
 font-family: monospace;
 font-weight: normal;
 vertical-align: top;
 margin: 0 .2em;
}

上記の例は、ユーザスタイルシートを利用することができるUAであれば、ユーザスタイルシートに記述して利用することもできます。

DOMを利用してアクセスキーを表示する。

前節の方法だと、MSIEのようにCSS2への対応が不完全なUAでは表示することができません(現状では、MSIEユーザが多いので困ったもの)。それでは、次の様にDOMを用いてECMAScriptで記述してみる方法はどうでしょうか?

次の例では、DOMを利用することでアクセスキーを表示することができる。

//=========================================================================
// アクセス・キーを表示する。
// 引数
//   arg (省略可): 囲み文字の開始文字と終了文字 [配列]
// 例
//   accesskeyMarks();           // 囲み文字は初期値: < >
//   accesskeyMarks(["[","]"]);  // 囲み文字の指定例: [ ]
// 出典
//   http://purl.org/net/osamurai/weblog/2004/03/18#blog.20040318.1.4
//=========================================================================
function accesskeyMarks(arg) {
  if (accesskeyMarks.arguments.length < 1 || arg.length < 2) arg = new Array("<", ">");
  var NodeList = {
    "a": document.getElementsByTagName('a'),
    "area" : document.getElementsByTagName('area'),
    "button" : document.getElementsByTagName('button'),
    "input" : document.getElementsByTagName('input'),
    "label" : document.getElementsByTagName('label'),
    "legend" : document.getElementsByTagName('legend'),
    "textarea" : document.getElementsByTagName('textarea')
    };
  for (var i in NodeList ) {
    for (var j=0; j<NodeList[i].length; j++) {
      var refElement = new Object(NodeList[i].item(j));
      refElement.attr = {
        "accesskey" : refElement.getAttribute('accesskey').toUpperCase(),
        "title" : refElement.getAttribute('title')
        };
      if (refElement.attr["accesskey"]) {
        var newElement = document.createElement('kbd');
        var newText = document.createTextNode(arg[0] + refElement.attr["accesskey"] + arg[1]);
        with (newElement) {
          appendChild(newText);
          setAttribute('class', 'accesskey');
          setAttribute('title', 'accesskey: '+ refElement.attr["accesskey"]);
        }
        //-----------------------------------------------------------------------
        // アクセス・キーを表示する。
        //-----------------------------------------------------------------------
        if (NodeList[i] == NodeList["input"]) {
          refElement.parentNode.insertBefore(newElement, refElement);
        } else {
          refElement.insertBefore(newElement, refElement.firstChild);
        }
        //-----------------------------------------------------------------------
        // ※以下の処理は、省略しても構わない。
        //-----------------------------------------------------------------------
        // accesskey属性と同時にtitle属性が存在するなら、序でにtitle属性値を再処理。
        //-----------------------------------------------------------------------
        if (refElement.attr["title"]) {
          refElement.setAttribute('title', arg[0] + refElement.attr["accesskey"] + arg[1] +': '+ refElement.attr["title"]);
        }
        //-----------------------------------------------------------------------
        // MSIEでは生成要素にCSSの設定が何故か反映されないので、仕方なくstyle属性を付与。
        //-----------------------------------------------------------------------
        with (newElement.style) {
          fontSize = ".83em";
          verticalAlign = "text-top";
        }
      }
    }
  }
}

上記の例は、然しながら、DOM Level 1 に対応しないUAでは利用できない。

最後に・・・

さて、ある要素に割り当てられたアクセスキーを表示する方法について触れてきたのだが、WCAG 1.0では、アクセシビリティーの向上の為にも重要なリンクやフォームにアクセスキーを割り当てることが推奨されています。そして、UA側でキーの割り当てを示すことができるようになるまでは、割り当てられているキーを示すようにとの注意書きも添えてあります。

音声読み上げソフトウェア(視覚障害者≠ホームページリーダー)を導入している環境では、どちらかのキーボード操作が不可能になるということは大変な致命傷です。現状では多くのUAは、UA側でアクセスキーを設定・変更できないので、過剰なアクセスキーの割り当ては本末転倒になりかねないので注意が必要です。

注釈

  • 本サイトのアクセスキーについては、ナビゲーションについてをご覧下さい。
  • 例で示すサンプルソースは、ご自由にご利用ください。また、改良を加えられた場合には、ご連絡を頂けると幸いです。