href="#"のみの指定はやめよう(フォーカス移動の問題点)
結論
「ページ上部に戻る」リンクは以下のように body
要素にid
を付与し、そのid
を参照するように実装して、フォーカスの移動が適切に行われるようにしましょう。
<body id="top">
...
<a href="#top">ページ上部に戻る</a>
</body>
href="#"
のみを指定した場合の挙動
「ページ上部に戻る」リンクが以下のようにして実装されているのをよく見かけます。
<body>
...
<a href="#">ページ上部に戻る</a>
</body>
Mozillaのアンカー要素ページにも以下のような記載があり、アンカー要素にhref="#top"
またはhref="#"
を使用すると、現在のページの先頭へのリンクになると、HTMLの仕様で定義されていることが分かります。
href="#top" または空のフラグメント (href="#") を使用すると、現在のページの先頭にリンクすることができると、 HTML 仕様書で定義されています。
ref: https://html.spec.whatwg.org/multipage/browsing-the-web.html#scroll-to-the-fragment-identifier
しかし、上記の実装のように「ページ上部に戻る」リンクにhref="#top"
またはhref="#"
を指定するだけだと、リンク押下後のフォーカス移動が適切に行われない場合があります。
例えば上記のような実装の場合、「ページ上部に戻る」リンクを押した後のフォーカス先は、文書の先頭を示すbody
要素であってほしいはずです。(ページに初めてアクセスしたときのフォーカス位置もbody
要素です)
しかし、Chrome、Safari、Firefoxでのフォーカス先は以下のように<a href="#">ページ上部に戻る</a>
要素のままとなっており、フォーカスの移動が行われていないことが分かります。
-
Chrome
-
Safari
-
Firefox
上記実装例の完全な実装はこちらのCodeSandboxから確認できます。
このように、「ページ上部に戻る」リンクにhref="#top"
またはhref="#"
を指定するだけでは、リンク押下後、body
要素へのフォーカス移動が行われないことが分かります。
body
要素にid="top"
を付与し、href="#top"
を指定した場合の挙動
では次に、以下のようにbody
要素にid="top"
を、「ページ上部に戻る」リンクにhref="#top"
を指定した場合の挙動を確認してみます。
<body id="top">
...
<a href="#top">ページ上部に戻る</a>
</body>
-
Chrome
-
Safari
-
Firefox
上記実装例の完全な実装はこちらのCodeSandboxから確認できます。
「ページ上部に戻る」リンクを押した後、適切に<body id="top">
へのフォーカス移動が行われていることが分かります。
つまり、HTMLの仕様では、アンカー要素にhref="#top"
またはhref="#"
を使用すると、現在のページの先頭へのリンクになると定義されていますが、これはページ先頭へのスクロールを行う仕様であり、フォーカスの移動については別途考慮する必要があります。
したがって、フォーカスの移動を適切に行うためには、「ページ上部に戻る」リンクはbody
要素にid
を付与し、そのid
を参照するように実装するのが最適だと考えます。
まとめ
「ページ上部に戻る」リンクは以下のように body
要素にid
を付与して、そのid
を参照するように実装して、フォーカスの移動が適切に行われるようにしましょう。
<body id="top">
...
<a href="#top">ページ上部に戻る</a>
</body>
参考文献
Discussion