img 要素に pointer-events:none; を指定すると、その画像を囲むリンクが効かなくなる件の回避方法

経緯

画像をむやみに右クリックで保存されないようにするため、img 要素に pointer-events:none; を指定した。

この CSS プロパティは、クリックや右クリックによるイベントを発火させなくするプロパティで、CSS の指定なのに JavaScript のイベント伝播にまで影響を与えてしまうシロモノ。サクッと画像保護チックなことができるので使ってみた。

これにより、画像の上で右クリックをしても、「名前を付けて画像を保存」といったコンテキストメニューが表示されなくなる。

事象

しかし、今回は img 要素を囲む a 要素が存在し、画像を右クリックで保存はさせたくないが、画像をクリックしてリンク先に遷移はさせたかった。しかし、img 要素に pointer-events:none; を指定すると、img 要素を囲んでいる a 要素のリンクも効かなくなってしまった。

対策

a 要素のリンクはそのまま効かせつつ、img 要素は右クリックしても「名前を付けて画像を保存」といったコンテキストメニューを表示させないようにするには、img 要素を囲んでいる a 要素に display:inline-block; を付与すると回避できた

a 要素に指定する display プロパティは inline-block だけでなく block でも良いが、inline では効果がなかった。

こうしてクリックできるようになった画像リンクは、右クリックをしても通常のテキストリンクの場合に表示されるようなコンテキストメニューのみで、「名前を付けて画像を保存」といったメニューは表示されていないので、画像保護っぽいことは上手くできている。

デモページで実際にお試しあれ

実際に失敗版と成功版を作ってみた。ついでに何も設定していない状態の通常版の画像も置いてみたので、それぞれでクリック時の動作やコンテキストメニューの内容などを確認してみてほしい。

この情報、pointer-events:none; を紹介している記事でも全然触れられておらず、自力で答えを見付けた。この記事を書くにあたって改めてそれっぽい単語で検索してみたところ、StackOverflow で少し話題になっていた。

デモページで使用しているダミー画像は、画像サイズや色、テキストなどを URL で指定するとその指定に沿って画像を生成してくれる「Dynamic Dummy Image Generator」というサービスを使っている。まさにコレが欲しかった、という感じ。