CSSのmaskでsvgを読み込めなかった件(CORSエラー)
コーディングの練習中でCSSのmaskプロパティでsvgファイルを読み込もうとした時、それができないことがありました。
maskプロパティとbackground-colorプロパティを使うことで、ボタンのマウスホバー時に画像の色を容易に変えることができます。しかし、、、、
<a href="" class="button">contact</a>
.button {
// 省略
}
.button::before {
content: "";
width: 18px;
height: 14px;
mask: url(../images/common/email.svg);
mask-size: cover;
background-color: #444;
display: inline-block;
}
こうなるはずなのに、
なぜかアイコンが表示されない。
ちなみに、maskではなくbackground-imageを使用したところ、画像は表示されました。
なぜか。
コンソールでのエラー
maskを使ったときのコンソールを開いてみると、以下のエラー文が出ていました。
日本語訳をすると、
オリジン「null」から「email.svg」の画像へのアクセスがCORSポリシーによってブロックされました。クロスオリジンリクエストは、chrome、chrome-extension、chrome-untrusted、data、http、https、isolated-appのプロトコルスキームでのみサポートされています。
とのこと。
CORSとは
英語で「Cross Origin Resource Sharing」といい、日本語では「オリジン間リソース共有」といいます。あるオリジンで動作しているWebアプリケーションが、別のオリジンにアクセスすることを許可する仕組みのこと。
オリジン間のデータアクセスにルールを設けることで、悪意あるサイトがユーザーの情報やデータを盗むことを防ぎます。セキュリティの向上に加え、柔軟なリソース共有や開発の効率化にもつながるそうです。
オリジンについては以下の記事がわかりやすかったです。
エラーの原因
maskを使ったときChromeのネットワークタブを見てみると、svgのリクエストヘッダーにOrigin: nullが入っていました。
おそらくこれが原因ですね。maskプロパティはoriginをリクエストするそうです。(background-imageを使ったときはこれはありませんでした。)
今回は私のPCで作成したローカルのhtmlファイルを読み込んでおり、URLが「file:///Users/〜〜」となっていました。なのでoriginがnullになり、CORSにブロックされてしまったのだと思います。
解決策
CORSのルールに従って、通信のプロトコルをhttpやhttps等にすれば解決すると思います。あるいは、maskやmask-imageを使わずにbackground-imageを使いましょう。
参考にしたサイト
Discussion