Front End Programming

CSSでaタグ(リンク)の当たり判定範囲を親要素に合わせる

CSS

※ 2020年3月21日にリライト済。
画像にリンクを貼りたい範囲より小さい時ってありませんか?
特にGoogleの推奨するボタンのタップサイズは44px以上ですが、画像がそれよりも小さく周りに余白を持たせ、そこもクリックないしはタップできるようにしないといけない。
そんな時わざわざ画像を再度大きく作り直さなくても、簡単に解決することができます。

アイコンを使って横並びのナビゲーションを作ってみよう

コーディング初心者であれば、こんな感じでナビゲーションを作って、あれ?なんでクリック範囲がうまくいかないんだってことになると思います。

おそらくこんなコード書いてるんじゃないかと思います。

html

 <ul>
  <li><a href="/home"><img src="img/icon-home.jpg" alt="ホーム" width="30" height="20"></a></li>
  <li><a href="/contact"><img src="img/mail-home.jpg" alt="メール" width="30" height="20"></a></li>
  <li><a href="/about"><img src="img/icon-about.jpg" alt="銀ねこさんについて" width="30" height="20"></a></li>
</ul>

CSS

ul {
    display: flex; 
    flex-wrap: wrap;
    border-right: 1px solid #aaaaaa; 
    list-style: none;
}

li {
    box-sizing: border-box; /* ボーダーや内側の余白を要素内に収める設定 */
    width: 33.3333%;
    border-left: 1px solid #aaaaaa;
    text-align: center;
}

a {
    box-sizing: border-box; /* ボーダーや内側の余白を要素内に収める設定 */
    padding: 10px; /* ←多分ここら辺で困っている */
}

なぜ、当たり判定がずれるのか?まずはaタグの特徴を知る

aタグHTML5では主にフレージングコンテンツの一種です。昔はinline要素に分類されており、特徴はそのままで段落内で使う文字の1個1個のような振る舞いをするタグです。

要素のカテゴリー分け

種類 タグ 備考
フローコンテンツ

<a>, <abbr>, <address>,
 <area> (map要素内にある場合)
<article>, <aside>, <audio>,
<b>, <bdi>, <bdo>, <blockquote>,
<br>, <button>, <canvas>, <cite>,
 <code>, <data>, <datalist>, <del>,
<details>, <dfn>, <div>, <dl>,
<em>, <embed>, <fieldset>,
<figure>, <footer>, <form>,
<h1>-<h6>, <header>,
<hr>, <i>, <iframe>, <img>,
<input>, <ins>, <kbd>, <keygen>,
<label>, <main>, <map>, <mark>,
<menu>, <meter>, <nav>, <noscript>,
<object>, <ol>, <output>, <p>, <picture>,
<pre>, <progress>, <q>, <ruby>, <s>,
<samp>, <script>, <section>, <select>,
<small>, <span>, <strong>, <sub>, <sup>,
<table>, <template>, <textarea>, <time>,
 <u>, <ul>, <var>, <video>, <wbr>, テキスト

 
メタデータコンテンツ <base>, <link>, <meta>, <noscript>, <script>, <style>, <template>, <title>  
ヘッディングコンテンツ <h1> ~ <h6> 見出し
セクショニングコンテンツ <article>, <aside>, <nav>, <section>  
フレージングコンテンツ <a>, <abbr>, <area> (map要素内にある場合)
<audio>, <b>, <bdi>, <bdo>, <br>, <button>,
<canvas>, <cite>, <code>, <data>,
 <datalist>, <del>, <dfn>, <em>, <embed>,
<i>, <iframe>, <img>, <input>, <ins>, <kbd>,
<keygen>, <label>, <map>, <mark>, <meter>,
<noscript>, <object>, <output>, <picture>,
<progress>, <q>, <ruby>, <s>,
<samp>, <script>, <select>, <small>,
<span>, <strong>, <sub>, <sup>,
<template>, <textarea>, <time>,
<u>, <var>, <video>, <wbr>, テキスト
 
エンベディッドコンテンツ <audio>, <canvas>, <embed>, <iframe>, <img>, <object>, <picture>, <video>  
インタラクティブコンテンツ <a> (HTML 5.1ではhref属性がある場合に限る),
<audio> (controls属性がある場合),
<button>, <details>, <embed>, <iframe>,
<img> (usemap属性がある場合),
<input> (type="hidden"の場合は除く),
<keygen>, <label>,
 <object>
(usemap属性がある場合)(HTML 5.1では除外),
<select>, <textarea>, <video> (controls属性がある場合)
 

プロパティは最初からdisplay: inlineがセットされており、テキストと同じような振る舞いをするのでボタンなどのカチッとした塊の要素にしたいときはスタイルを調整する必要があります。広げ方は簡単。display: block; を指定するだけです。プロパティの display を block に変更することで、親要素いっぱいに幅が広がります。

a {
    box-sizing: border-box;
    display: block;
}

imgタグも同じフレージングコンテンツ

リンク貼る画像がリンクさせたい範囲より小さい場合、aタグに入れ子になったimgタグは性質上、左寄せになってしまいます。

aタグ同様imgタグもフレージングコンテンツです。親要素が display: block; など指定しているのであれば、そのまま親要素に text-align: center; なのでセンタリングするのが手っ取り早いです。

a {
    display: block;
    text-align: center;
    padding: 10px 0; /* 上下に余白を入れる */
}

さらにflexを使ってバージョンアップ

2009年あたりからフレキシブルレイアウトモジュール(いわゆる、flex)なるものが登場しました。度重なる進化を遂げて今やレイアウト作成の鉄板プロパティーです。

flexible box layout moduleについて

メインでヘッダーを固定してナビゲーションを置きたいのであればナビゲーションを1ピクセル単位で調整したくなると思います。
なのでaタグの高さを決めてしまい、display: flex; で上下左右中央に画像を持っていくのがオススメです。

html

 <ul>
  <li><a href="/home"><img src="img/icon-home.jpg" alt="ホーム" width="30" height="20"></a></li>
  <li><a href="/contact"><img src="img/mail-home.jpg" alt="メール" width="30" height="20"></a></li>
  <li><a href="/about"><img src="img/icon-about.jpg" alt="銀ねこさんについて" width="30" height="20"></a></li>
</ul>

CSS

ul {
    display: flex;
    flex-wrap: wrap;
    border-right: 1px solid #aaaaaa;
    list-style: none;
}

li {
    box-sizing: border-box; /* ボーダーや内側の余白を要素内に収める設定 */
    width: 33.3333%;
    border-left: 1px solid #aaaaaa;
    text-align: center;
}

a {
    box-sizing: border-box;
    display: flex;
    text-align: center;
    height: 50px;
    justify-content: center;
    align-items: center;
}

まとめ

タグの振る舞いを変えるためにはプロパティdisplayを制すべし!!

そのほか、display: sticky; など昔が考えられなかった面白い値もあります。
display周りを使いこなせると、とてもコーディングの幅が広がります。

この記事がみなさんのコーディングライフの一助となることを願っています。
最後まで、お読みいただきありがとうございました。

関連記事もあわせてお読みください

Read More

記事のジャンル

管理人について

私、フロントエンドエンジニアのかみーゆです。日本でフロントエンドを中心に10年以上Web制作 →→→ セブ島に転職してエンジニア講師 →→→ オフショア開発担当者(イマココ)。13歳の頃から「好きなように生きて好きなように死ぬ」が人生のKPI。なので、「楽しいか」、「かっこいいか」でやることを判断・取捨択一しています。好きなものは肉とビール。

About Me