概要
URL#アンカー名
のアンカー名はid
属性と、後方互換としてa
要素のname
属性が使える場合がある。
では、ある要素のid
属性とa
要素のname
属性が被った場合、
URL#アンカー名
はどちらへ飛ぶのか?
結論
ブラウザによって異なる。
nameが先 | idが先 | nameのみ | |
---|---|---|---|
Firefox46 | id | id | name |
Chrome50.0.2661.94 m | id | id | name |
IE11 | name | id | name |
IEのみ先に出たものを採用するような結果となった。
当然ながらid
とname
は被らないようにしよう。
もしアンカーリンクが意図しない場所へ飛び、うまく再現しない、特定のブラウザのみで起こるなどの場合は、a
要素のname
属性を疑ってみる。
あらすじ
HTMLにはページ内リンクとして、特定の箇所にジャンプする機能がある。
URL#アンカー名
へ遷移することで、目的のアンカー要素がある場所へスクロールされた状態でそのページが表示される。
アンカーはユニークでなくてはならないので、id
属性を使う。
なので、どんな要素でもid
をつければジャンプできるようになる。
…というのが無勉強時の認識だった。
id
属性登場前、つまりHTML4以前では、このアンカーはa
要素のname
属性が担当していた。
そして現在でも後方互換ということで、a
要素のname
属性でのジャンプが可能なようだ。
-
URL#アンカー名
はid
かa
要素のname
を指す -
id
とname
は共通の名前空間を使用する -
id
とname
が重複することは仕様上正しくない
ということがわかった。
しかし人は間違いを犯すもので、このルールを知らずにid
とa
要素のname
が被り、同名のアンカーが発生した場合、ブラウザはどちらのアンカーを使用するのかが気になった。
仕様確認
アンカーの経緯
以前はa
要素のname
属性を使っていたが、HTML4からid
属性が追加された。
特に目的地のa
要素は空にして、視覚上表示されない終点アンカーとして使われていたそうだ。
公式な仕様勧告ではないですが、
アンカーの最適化|最適化|Web標準
a要素に name属性を指定する目的地アンカー(終点アンカー)は、従来の HTML によく用いられる手法ですが
,
従来はウェブページ内の特定箇所を参照する方法は a要素の name属性による目的地アンカーのみに限られていましたが、id属性は他の要素に指定してもウェブページ内の特定箇所をリンク先として参照させることが可能です。
,
Web標準技術の視点において、過去の規格において有効であった name属性を使用するのではなく、将来的にも通用する id属性を採用するのは至極当然のことでしょう。
HTML4.01仕様書
id
属性が追加されたHTML4の仕様書にアンカーに関する記述が見つけられた。
HTML5の勧告には見つけられないか、日本語訳されていないようだ。
仕様策定団体について詳しくないので、公式文書(それも私家訳)の検索にはかなり粗があることを先に述べておく。
12.1.1 リンク先リソースの訪問
HTML文書中の終点側アンカーは、A要素( name属性で命名される)によっても、また他の要素(id で命名される)によっても、指定できる。
a
要素のname
属性は廃止されたわけではないようだ。
Links in HTML documents (ja)#anchors-with-id
id
とname
アンカーについて書かれている。
id属性とname属性は、同じ 名前空間を共有する。 これはつまり、同一文書では、両属性が、あるアンカーに同じ名前を定めることができないということを意味する。 次の要素においては、両属性で、文書中で固有となる識別子を指定することが許される。 A、APPLET、FORM、FRAME、 IFRAME、IMG、及びMAP要素である。 単一要素中で両属性が用いられる場合、各々の値は同一でなければならない。
id
とname
の名前空間の共有がポイントだ。また、
両属性で、文書中で固有となる識別子を指定することが許される。
が意味が読み取れなかった。
不正な例:
次の例は、同一文書中で、各属性が同じ名前を重ねて宣言しているので不正なHTMLとなっている。
<A href="#a1">…</A>
…
<H1 id="a1">
…中略…
<A name="a1"></A>
この不正なHTMLをブラウザがどう解釈するかというのが今回の検証だ。
id属性を使うか、name属性を使うか? 著者は、アンカー名にid属性を使うか name属性を使うかを決定する際に、次の内容を吟味する必要がある。
- id属性は、アンカー名である以上の役割を果たす。例えば、スタイルシート選択子、プログラム処理の識別子など。
- 古いユーザエージェントの中には、id属性によるアンカーをサポートしないものもある。
- name属性の方が、命名の自由度が高い。実体を利用できる。
流石に最近のブラウザではid
属性に対応しているだろうが。
ここでもname
属性も否定的には書かれていない。
検証コード
<body>
<div>
<a href="#jump1">jump1 name id 順で飛びます</a>
<a href="#jump2">jump2 id name 順で飛びます</a>
<a href="#jump3">jump3 name だけで飛びます</a>
</div>
<a name="jump1">nameに飛びます(jump1)</a>
<a id="jump1">idに飛びます(jump1)</a>
<a id="jump2">idに飛びます(jump2)</a>
<a name="jump2">nameに飛びます(jump2)</a>
<a name="jump3">nameに飛びます(jump3)</a>
</body>
a {
display:block;
}
body>a {
margin-top: 1000px;
}
動作は結果を参照。