要するに background-image: url(...);
で SVG を使うまとめです。プレゼントもあるよ。
対象
- とにかく手っ取り早く SVG を使いたい人
- フリーの SVG 素材で間に合わせたい人
- HTML に SVG タグを埋め込みたくない人
- SVG スプライトも Web フォントも使いたくない人
- IE 11 でも表示したい人
という出不精な人向けの記事です。
想定
下記の要素に「顔の形をした」 SVG を表示したいとします。
<i class="c-icon--face"></i>
手順
- とにかく Material Design Icons を開きます
-
Search...
ボックスにface
と入力します - 一覧からお好みの SVG をクリックします
-
</>
ボタンを押し、プルダウンメニューからView SVG
を選択します - テキストエリアの中身をすべてコピー…するのではなく、
d
属性の中身のみコピーします。<path fill="#000000" d="..." />
の...
です - 下記のようなスタイルシートを記述し、
...
の部分にコピーした内容をペーストして完了です
<style>
.c-icon--face {
background: url('data:image/svg+xml;charset=UTF-8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24"><path fill="%23000000" d="..." /></svg>') no-repeat center center;
display: block;
width: 128px;
height: 128px;
}
</style>
必要であれば background-size
をいじってサイズを変更できます。
補足
でもこれ CSS で色変えられなくない?
はい、背景画像なので CSS の fill
プロパティや stroke
プロパティは適用されません。
適宜 fill="%23000000"
の 000000
の部分を変えてください( 16 進数表記の場合)。
追記: 嘘です。本当は mask
プロパティを使えば変えられます(この記事を書いた時は対応ブラウザにやや難があったんですが、今はもう大丈夫でしょう)。単純に background
を mask
にして、 background-color
に色を指定すれば OK です。
.c-icon--face {
background-color: #ff0000;
mask: url('...') no-repeat center center;
display: block;
width: 128px;
height: 128px;
}
なんで '#' を '%23' にしてるの?
Chrome の Deprecation Warning 避けです。
[Deprecation] Using unescaped '#' characters in a data URI body is deprecated and will be removed in M71, around December 2018. Please use '%23' instead.
Stylus のカラー変数を反映させたいんだけど
$encodeColor(color)
replace("#", "%23", s("%s", color))
というような mixin を作り、以下のように使うと良いと思います。
<path fill='" + $encodeColor(black) + "' d="..." />
なんで d
属性値だけコピペするの?
SVG を background-image
として使うには、 svg
タグに xmlns
属性を記述する必要があります。が、 Material Design Icons の SVG には記述されていないためです。
また、 Material Design Icons の SVG は d
属性値以外はすべて同一であることから(たぶん)、複数の SVG を扱う際には上記の手順を踏むことになると思います(そういう意味では mixin を用意しても良いかもしれません)。
content
プロパティには使えるの?
content: url('...');
でも良いのですが、一部の環境で表示がおかしくなった…ような記憶があります(曖昧)。
動作確認環境
- MacOS 10.14.2 + Chrome 71
- MacOS 10.14.2 + Firefox 64
- MacOS 10.14.2 + Safari 12
- MacOS 10.14.2 + Simulator + iPhone 5s + iOS 12.1 + Safari
- MacOS 10.14.2 + Genymotion + Google Nexus 4 + Android 4.4 + 標準ブラウザ
- Windows 10 + Chrome 71
- Windows 10 + Firefox 64
- Windows 10 + Edge 42
IE 11 で使うには
上記のリストに、
- Windows 10 + IE 11
を加えるためには一手間必要です。
手順
- 前述した CSS の
data:image/svg+xml;charset=UTF-8,
をdata:image/svg+xml,
にします -
svg
要素全体を JavaScript のencodeURI
関数などで URL エンコードします -
#
を%23
に変換して完了です
説明
まず、 IE 11 で SVG Background Image を使うには、 svg
要素全体を Base64 エンコードか URL エンコードしてやる必要があるようです。ここでは少しでも可読性の高い URL エンコードを採りました。
次に、エンコードに使用する関数としては encodeURIComponent
…であれば一発なのですが、ここでも可読性を高めるために encodeURI
を使っています。
ただし encodeURI
では #
が変換されないので、 %23
に変換する必要があります。
面倒くさいんですけど!
という人向けに Material Design Icons でのみ使えるお便利ブックマークレットを用意しました 🎁
SVG のコードが表示されている状態(共通手順の 5. の画像の状態)で呼び出してください。 IE 11 に対応した Data URI scheme を表示してくれるので、後は background-image: url(...);
の ...
にコピペするだけです。
javascript: (() => { const svg = encodeURI(document.querySelector('[ng-model="code.svgTag"]').value.replace(/<svg[^>]*?>/, '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">')).replace(/#/g, '%23'); prompt('', `data:image/svg+xml,${svg}`); })(); void 0;
最後に
大人しく SVG スプライトを使った方が良いと思います。はい。