Webサイトを作成したらタブキーで移動できるかチェックしよう

キーボードのタブキーで移動できるか

Webサイトはマウスだけでしか操作ができないとユーザビリティが低下するのでキーボードだけでも操作できるようにしたほうが理想的だ。

しかし残念ながら日本のWebサイトではキーボードのタブキー(Tab)でフォーカスが正しく移動できないWebサイトが多い。

この記事ではフォーカスで問題が発生する原因と対処法について解説しています。

※ Safariはタブキーを押してもフォーカスがまともに機能しないので無視して良いです。

outline: none; にしてはいけない

日本のWebサイトで特に多いのがaタグなどのoutlineプロパティをnoneにしてフォーカス時の輪郭線を消してしまっているケースだ。

例えば楽天のWebサイトのトップは順当に行けば「ロゴ => キーワード検索 => 買い物かご」の順にフォーカスされるのが正しいはずだが、outline: none;が適用されているため「買い物かご」がフォーカスされても輪郭線が表示されない。

https://www.rakuten.co.jp/

ほかにもCygamesスクエニなど多くのWebサイトでCSSでoutline: none;が記述されていることが原因でフォーカス時の輪郭線が表示されないことが確認できる。

ちなみにConsoleで以下のコマンドを実行すると強制的にフォーカス時のoutline: none;の指定を解除できるので試してほしい。

const css = ':focus { outline: auto !important; }';
const style = document.createElement('style');
document.head.appendChild(style);
style.appendChild(document.createTextNode(css));

tabindexが適切に指定されていないケース

outline: none;が指定されていなくてもtabindexが適切に指定されていないとタブキーでフォーカスを正しく移動できない。

例えば以下のようにtabindexが1, 2, 3の順序で指定されていてbarとbazの間にaddというボタンがtabindex属性を付けずに追加された場合、barの次にaddに対してフォーカスが当たらなくなってしまう。

<!-- addボタン追加前 -->
<ul>
  <li><button tabindex="1">foo</button></li>
  <li><button tabindex="2">bar</button></li>
  <li><button tabindex="3">baz</button></li>
</ul>
<!-- addボタン追加後 -->
<ul>
  <li><button tabindex="1">foo</button></li>
  <li><button tabindex="2">bar</button></li>
  <li><button>add</button></li>
  <li><button tabindex="3">baz</button></li>
</ul>

tabindex属性の順序がおかしくなっているサンプル

こういうことが起きないように本当に必要なケースでなければtabindex属性を付けないか、必要な場合はtabindex="0"で指定してコードの記述順にフォーカスさせるのが望ましい。

mixiのように必ず最初にログインメールアドレスにフォーカスさせる場合などはこの限りではない。

マウスオーバーでリンクが表示される場合

メニューをマウスオーバーすることでサブメニューが表示されるWebサイトの場合、何も対策をしていなければタブキーでフォーカスを移動しても非表示になっているためユーザーは視認することができない。(例: DeNA)

マウスオーバーでサブメニューが表示されないサンプル

こうならないようメニューのフォーカス時は:focus-withinを使用してサブメニューを開くようにしたほうが好ましい。

.menu > li:focus-within > ul,
.menu > li:hover > ul {
  opacity: 1;
}
Webサイトを作成したらタブキーで移動できるかチェックしよう

マウスオーバーでサブメニューが表示されるサンプル

tabindex="-1"でフォーカスさせない

前述のサブメニューはフォーカスさせていたが、サブメニューが多すぎる場合はフォーカスさせたくない場合もある。

そんなときはリンクにtabindex="-1"を追加すれば該当のリンクをフォーカスの対象外にできる。

<ul class="menu">
  <li>
    <a href="#">menu1</a>
    <ul>
      <li><a href="#" tabindex="-1">sub1</a></li>
      <li><a href="#" tabindex="-1">sub2</a></li>
      <!-- 以下略 -->
    </ul>
  </li>
  <li><a href="#">menu2</a></li>
  <li><a href="#">menu3</a></li>
</ul>

tabindex="-1"のサンプル