10
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

(不正だけど)nameとidが被ったアンカー(#value)がどうなるか

Posted at

概要

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のみ先に出たものを採用するような結果となった。

当然ながらidnameは被らないようにしよう。
もしアンカーリンクが意図しない場所へ飛び、うまく再現しない、特定のブラウザのみで起こるなどの場合は、a要素のname属性を疑ってみる。

あらすじ

HTMLにはページ内リンクとして、特定の箇所にジャンプする機能がある。

URL#アンカー名
へ遷移することで、目的のアンカー要素がある場所へスクロールされた状態でそのページが表示される。

アンカーはユニークでなくてはならないので、id属性を使う。
なので、どんな要素でもidをつければジャンプできるようになる。

…というのが無勉強時の認識だった。
id属性登場前、つまりHTML4以前では、このアンカーはa要素のname属性が担当していた。
そして現在でも後方互換ということで、a要素のname属性でのジャンプが可能なようだ。

  • URL#アンカー名ida要素のnameを指す
  • idnameは共通の名前空間を使用する
  • idnameが重複することは仕様上正しくない

ということがわかった。
しかし人は間違いを犯すもので、このルールを知らずにida要素のnameが被り、同名のアンカーが発生した場合、ブラウザはどちらのアンカーを使用するのかが気になった。

仕様確認

アンカーの経緯

以前はa要素のname属性を使っていたが、HTML4からid属性が追加された。

特に目的地のa要素は空にして、視覚上表示されない終点アンカーとして使われていたそうだ。

公式な仕様勧告ではないですが、
アンカーの最適化|最適化|Web標準

a要素に name属性を指定する目的地アンカー(終点アンカー)は、従来の HTML によく用いられる手法ですが

,

従来はウェブページ内の特定箇所を参照する方法は a要素の name属性による目的地アンカーのみに限られていましたが、id属性は他の要素に指定してもウェブページ内の特定箇所をリンク先として参照させることが可能です。

,

Web標準技術の視点において、過去の規格において有効であった name属性を使用するのではなく、将来的にも通用する id属性を採用するのは至極当然のことでしょう。

HTML4.01仕様書

id属性が追加されたHTML4の仕様書にアンカーに関する記述が見つけられた。
HTML5の勧告には見つけられないか、日本語訳されていないようだ。
仕様策定団体について詳しくないので、公式文書(それも私家訳)の検索にはかなり粗があることを先に述べておく。

Links in HTML documents (ja)

12.1.1 リンク先リソースの訪問
HTML文書中の終点側アンカーは、A要素( name属性で命名される)によっても、また他の要素(id で命名される)によっても、指定できる。

a要素のname属性は廃止されたわけではないようだ。

Links in HTML documents (ja)#anchors-with-id
idnameアンカーについて書かれている。

id属性とname属性は、同じ 名前空間を共有する。 これはつまり、同一文書では、両属性が、あるアンカーに同じ名前を定めることができないということを意味する。 次の要素においては、両属性で、文書中で固有となる識別子を指定することが許される。 A、APPLET、FORM、FRAME、 IFRAME、IMG、及びMAP要素である。 単一要素中で両属性が用いられる場合、各々の値は同一でなければならない。

idnameの名前空間の共有がポイントだ。また、

両属性で、文書中で固有となる識別子を指定することが許される。

が意味が読み取れなかった。

不正な例:
次の例は、同一文書中で、各属性が同じ名前を重ねて宣言しているので不正な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;
}

動作は結果を参照。

その他参考

10
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?