SVGのpointer-events:画像に合うクリック領域を作る
塗り、ストローク、穴、別のヒット領域でSVGのクリック範囲を制御します。イベントの対象を検証し、キーボード操作は標準のボタンやリンクに持たせます。
目次
SVGのpointer-eventsは、画像のどの部分がポインターイベントの対象になるかを制御します。同じイラストでも、塗り形状、細いストローク、空の穴は異なる反応をする場合があります。読者が期待する操作に合わせてヒット領域を設定し、色のある部分だけでなく空の部分も慎重にテストします。
このガイドは、選択できる図、クリック可能なエンブレム、ボタン内のアイコンなど、Webインターフェースの画像向けです。SVGに使えるパスがすでにあるなら、操作コードを直接修正します。ベクター化が必要なのは、編集可能な形状がまだPNGやJPG内にある場合だけです。
クリックを受ける要素から始める
SVGの既定値autoは、visiblePaintedと同じように動作します。見える形状では、fillがnoneでなければ塗り、strokeがnoneでなければストローク上が対象になります。SVGの操作仕様が、これらのヒット判定規則を定義しています。
そのため、一見壊れたアイコンでも、リスナーが輪郭上では動き、空の中心では反応しない場合があります。ブラウザーは形状を判定し、周囲の矩形内のすべての点が同じ意味だとは想定しません。
この手順で役立つ選択肢は次のとおりです。
| 値 | 用途 |
|---|---|
auto | 見える描画済みの塗りとストロークで対象を決めます |
stroke | 開いた線も含め、ストローク領域を対象にします |
fill | 塗りがnoneでも形の内部を対象にします |
all | 描画や可視性を条件とせず、塗りとストローク領域を対象にします |
none | この要素をポインターの対象から除外します |
allは「SVGビューポートのすべての点」ではありません。依然として要素の形状を指します。繊細な画像の周囲の特定の矩形を反応させたい場合は、その矩形を意図して作ります。
透明な塗りと塗りなしも区別します。fill="transparent"も塗りの値ですが、fill="none"は塗りをなくします。不透明度だけでは、オーバーレイにクリックを無視させる確実な方法になりません。
塗り、穴、開いたストロークを試す
独自の手書き形状を持つ小さなインラインSVGの実験ページを作りました。矩形の穴のある青い複合パス、オレンジの開いたストローク、別の透明な対象上に置いたそのストロークのコピーがあります。学習用の例で、PerfectVectorの変換結果ではありません。

ブラウザーテストでは、青い帯のクリックはring、空の中心は包含するSVGのring-stageと記録されました。オレンジの線はtrail、頂点の下の空間はstroke-stageでした。3つ目のパネルでは、両方の位置がhitでした。
青いパスは2つの矩形サブパスとfill-rule="evenodd"を使います。
<svg id="ring-stage" viewBox="0 0 240 180">
<path id="ring" fill="#2874c8" fill-rule="evenodd"
d="M30 20H210V160H30Z M85 60H155V120H85Z" />
</svg>偶奇の塗り規則では、内側の矩形は塗り領域の外です。実際の穴です。上に重ねた白い矩形なら、別の描画形状として固有のヒット動作を持ちます。形状自体が誤っている場合は、イベント規則を変える前にSVGの穴の修復ガイドを使います。
2つ目のパネルの開いたストロークは次のとおりです。
<svg id="stroke-stage" viewBox="0 0 240 180">
<path id="trail" d="M30 140L120 35L210 140"
fill="none" stroke="#db704c" stroke-width="12"
pointer-events="stroke" />
</svg>簡単に試すには、どちらかのコードをHTMLへ置き、その後に次の記録処理を置きます。SVGにwidth="360" height="270"などの見えるサイズを与えます。
<output id="result" aria-live="polite">Click the artwork.</output>
<script>
const stage = document.querySelector('svg');
const result = document.querySelector('#result');
stage.addEventListener('click', (event) => {
result.textContent = `Target: ${event.target.id}`;
});
</script>描画領域、空の内部、画像外の隅をクリックします。event.targetの記録で、パスのヒットと、単にSVGコンテナーへ届いたクリックを区別できます。この例は対象選択のテストで、完成した操作部品ではありません。
画像を太くせずヒット領域を加える
オレンジの線の周囲全体で線を選択させたい場合を考えます。見えるストロークを太くすると、イラストが変わります。別の対象なら、操作領域に固有の形状を使えます。
<svg id="hit-stage" viewBox="0 0 240 180">
<rect id="hit" x="20" y="20" width="200" height="140"
fill="transparent" pointer-events="all" />
<path d="M30 140L120 35L210 140"
fill="none" stroke="#db704c" stroke-width="12"
pointer-events="none" />
</svg>矩形は画像の背後にあります。オレンジのパスはポインターの対象にならないため、その上から矩形へクリックが届きます。座標で意図した対象を明示し、見えるパスデータは2つ目のパネルと同じままです。
図の領域や、指しにくい細い線に役立ちます。無関係な操作部品と対象を重ねず、2つの領域が接する場所の動作を決めます。大きな不可視形状も、見える形状と同様に隣のクリックを奪う場合があります。
1つの操作を行う単純なアイコンなら、SVG矩形を加えず、標準のHTMLボタンで必要な対象を作れる場合が多くあります。
キーボード操作は操作部品に持たせる
ポインターの対象設定は、ラベル、キーボード操作、ボタンの意味を提供しません。単一操作のアイコンは名前のあるHTMLボタンに入れ、画像は装飾にします。
<button id="select-trail" type="button">
<svg aria-hidden="true" viewBox="0 0 24 24"
width="24" height="24" style="pointer-events: none">
<path d="M3 20L12 4L21 20" fill="none"
stroke="currentColor" stroke-width="3" />
</svg>
Select trail
</button>
<output id="selection" aria-live="polite"></output>
<script>
const button = document.querySelector('#select-trail');
const selection = document.querySelector('#selection');
button.addEventListener('click', () => {
selection.textContent = 'Trail selected';
});
</script>標準のbutton要素が操作動作を提供し、見える文字が名前になります。見えるフォーカス表示を残します。別のページへ移動する操作には、実際のリンクを使います。
実験ページでは、Tabでボタンへフォーカスし、EnterとSpaceでそれぞれ操作できました。実際のインターフェースでもそのキーをテストします。複数の独立操作のある図には、その操作に適したキーボード設計が必要です。図全体を囲む1つのボタンでは、すべての操作を表せません。
pointer-events: noneは無効状態でもありません。本来フォーカスできる操作部品を、キーボード移動から除外しません。MDNはキーボードフォーカスとイベント伝播を説明しています。子孫は再び対象になるよう設定でき、そのイベントは親のリスナーを通る場合があります。ボタンを無効にするには、標準のdisabled属性を使います。
開始画像がPNGの場合
平面的なPNGやJPGしかなく、インターフェースに独立して編集可能な形状が必要なら、PerfectVectorの画像をベクターに変換する手順でSVG候補を準備できます。元画像と比較し、重要な穴と領域を確認して、別の操作対象を持たせる部分を決めます。
トレースは形状を提供します。意味のあるID、操作ハンドラー、名前、フォーカス動作、意図したヒット領域はアプリ側に必要です。トレースした見た目の輪郭は、ユーザーがクリックするべき領域より細かい場合があります。小さなUIアイコンには、手動の描き直しや既存のベクターマスターが管理しやすい場合があります。PNGアイコンの準備ガイドは、復元画像をUIキットへ入れる前の確認を説明しています。
操作部品内の装飾アイコンなら、CSSマスクアイコンが色の挙動に適する場合があります。操作は周囲の部品が担います。ベクター化ガイドは、そもそもパスの復元が役立つ場合を扱っています。
公開前に意図した領域を検証する
大きなエディタープレビューだけでなく、実際の表示サイズで試します。
- 塗り領域、ストローク、各穴、空の隅をクリックします。
- 誤った操作が起きたらイベント対象を調べます。
- ポインターを奪う透明矩形やオーバーレイを確認します。
- 隣の対象が予期せず重ならないか確認します。
- 適切な場所でTab、Enter、Spaceを使い、フォーカスを表示します。
- 対応するデバイスでタッチ操作をテストします。
実験ページは1つのブラウザーでこの特定形状を検証しています。マスク、クリッピング、フィルター、複雑な読み込み画像でのすべてのブラウザーの動作を証明しません。デザインにそれらがあれば、自分のテストへ加えます。
編集可能な形状がないなら、PerfectVectorで元画像を試し、輪郭と穴を確認します。画像が正しくなった後、操作領域を別途定義してテストします。
よくある質問
SVGの輪郭をクリックしたときだけ反応するのはなぜですか? 既定のSVGのポインター動作では、塗りのない形状は描画したストローク上だけが対象になる場合があります。塗りの値と意図した操作を確認します。空白も同じ操作を起動するなら、意図したヒット領域や周囲の標準部品を使います。
pointer-events="all"はSVG全体をクリック可能にしますか?
描画や可視性の値に関係なく、要素の塗りとストローク領域を対象にします。SVGビューポート全体が自動で対象になるわけではありません。その領域が必要なら、明示的な形状か周囲の操作部品を使います。
透明な矩形はクリックを受け取れますか? はい。透明だから形状や塗りがないわけではありません。適切なpointer-events値の透明矩形は意図したヒット領域に使えますが、誤ってクリックを奪う場合もあります。
画像をベクター化すると、アクセシブルなボタンができますか? いいえ。ラスターから編集可能な形状を作れますが、名前、キーボード動作、操作ハンドラー、フォーカス、操作領域はインターフェースで実装・検証する必要があります。
参考資料
- W3C — SVG 2のスクリプトと操作 — ポインターの対象とpointer-events値が使う形状を定義しています。
- W3C — SVG 2の描画 — 塗り規則がパスの内部と穴を決める方法を定義しています。
- MDN — pointer-events — 対象、伝播、継承、キーボードフォーカスの制限を説明しています。
- MDN — button要素 — 標準ボタンの動作、名前、無効状態を説明しています。

