アンカーの子要素の余白

HTML Standardsではa要素の子にh1とかpとか果てはsection要素まで含めることが出来る。その場合、子要素のmarginプロパティーによる余白があったりするわけだけど、その余白部分もリンクになるかどうかはブラウザーによって違うようだ。

Demo: Block Anchor

デモに書いてあるように、余白(見出しと段落の間)がリンクになりクリックできるのはChrome 29だけ(結構な頻度でリンクにならないことがあるけど)。Internet Explorer 10とFirefox 23ではリンクにならずクリックできない。どうなるべきか根拠になりそうな仕様は見つけられなかった。

この挙動の違いをブラウザー間で揃えるには、CSSでa要素にdisplay: inline-blockするか、a要素の子要素でmarginプロパティーの代わりにpaddingプロパティーを使う必要がある。前者の方がまだマシだが、どちらの方法もそこそこコストが高いので、a要素が複数の子要素を保たないようにマークアップを変更する方が無難な気がする。

<a>
  <section>
    <h1>...</h1>
    <p>...</p>
  </section>
</a>

デモのマークアップの場合は上記のようにa要素でsection要素全体を括るように修正する。これだけでどのブラウザーでも余白がリンクになりクリックできるようになる。マークアップの都合上div要素を使う必要があったりもするので、そういうのが気になる場合はa要素にクラスを振りdisplay: inline-blockを使うと良い。将来的には以下のように書けるようになるはずだけど今は書けないので。

a! > :matches(h1, p, hr, pre, ol, ul, dl, div) {
  display: inline-block;
}

セレクターの途中を選択する!(頭に$じゃなくなった)と、既にベンダー拡張プリフィックス付きで:any()としていくつかのブラウザーで実装されている:matches()の組み合わせ。わぁわかりやすい!


いずれにしろアンカーの子要素の余白はリンクにならずクリックできないという前提の元に、どう振る舞わせるのが良いかを考える必要がありそう。