[70-5] 複数のSVGを1つにまとめて個別に呼び出す SVGスプライト

最終更新日:2017年11月15日  (初回投稿日:2017年05月08日)

複数のSVG画像のコードを1つにまとめておいて、HTML上で個別に呼び出すことを、 SVGスプライト(SVG Sprite)というと言うんだそうで、今回はこれを使ってみます。

SVGはコードが長くなりがちなので、同じ図形を何度も使う場合、使用する箇所ごとにいちいち同じコードを書くのは面倒。
そこで、SVGをまとめて書いておき、図形を貼りたい箇所で呼び出すようにすれば、何度も同じコードを書かなくて済み、編集もラクになるというわけです。
アイコンなどページ内で同じものを何度も使うなら、SVGスプラウトにしたほうが便利です。

SVGスプライトは、<body>直下にジカに書く方法と、SVGを外部ファイルにして呼び出す方法があるそうなんですが、今回はせっかくなので外部ファイルにする方法をやってみます。

本日のINDEX
  1. 複数の図形を1まとめに作る(Illustrator)
  2. 書き出したSVGファイルを編集する
    1. <svg>要素のみにして、余計なものは削除
    2. <g>要素を<symbol>要素に書き換え、viewBox属性もここに
    3. <symbol>要素にする利点
  3. HTML上に SVGファイルを呼び出す
    1. jQueryを使う方法
    2. PHPならたった1行
    3. 外部SVGファイルの <svg>要素を display:none にする
  4. SVG画像を使いたいところに<use>要素で呼び出す
  5. CSSでサイズなどを指定
今回使用する要素 <symbol> 〜 </symbol>
<use />(終了タグはありません。XMLなので最後に/が必要)

複数の図形を1まとめに作る(Illustrator)

今回のサンプルはこちらです(クリックで別ウィンドウで開きます)

今回は、レストランのメニューなどで使う食品のアレルゲンのアイコンを作ってみました。
Illustratorで アイコンが全部出来上がったら、アートボードはアイコンのサイズにし、各アイコンを重ねてしまいます。
このほうが、図形の基点(左上)が全部 x=0 y=0 になって呼び出しやすいから。
各アイコンはレイヤーを分けて、レイヤー名をちゃんとつけておきます。

Illustrator で SVG を描くときのアートボードの編集などは
[70-1] svg要素でベクターグラフィクスを埋め込もう をご覧ください。

書き出したSVGファイルを編集する

Illustratorで画像ができたら、SVGファイルに書き出します。
(書き出し方は [70-1] svg要素でベクターグラフィクスを埋め込もう をご覧ください)

Illustratorのファイルと同名の、拡張子が「.svg」になったファイルができますので、これをテキストエディタとか Dreamweaverやらで開いてコードを編集します。

編集の要点は、
1. <svg>要素のみにして、余計なものは削除
2. <svg>要素の属性を整理する(名前空間宣言を残す)
3. 各アイコン画像は<g>要素でグルーピングされているが、これを<symbol>に書き換える
4. <symbol>要素に viewBox属性を書いておく

といった感じです。

<svg>要素のみにして、余計なものは削除

Illustratorが書き出したファイルがこちら↓ 主役の<svg>要素の上のハイライト部分を削除します。(<svg>〜</svg>だけを残すってことです)

Illustratorが書き出したSVGファイル

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
	 x="0px" y="0px" width="47px" height="50px" viewBox="0 0 47 50" 
	 enable-background="new 0 0 47 50" xml:space="preserve">
<g id="milk">
	<path fill="#D0A195" d="M47,..."/>
	<!-- パスなどのコード。長いので略 -->
</g>
<g id="wheat">
	<path fill="#D0A195" d="M47,..."/>
	<!-- 長いので略 -->
</g>
<g id="egg">
	<path fill="#D0A195" d="M47,..."/>
	<!-- 長いので略 -->
</g>
</svg>

<svg>要素のみにして編集したのがこちら↓(他にも<symbol>要素が登場したりしていますが順に説明します)

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" class="allergen-icon">
 <symbol id="milk" viewBox="0 0 47 50">
	<!-- パスなどのコード。長いので略 -->
 </symbol>
 <symbol id="wheat" viewBox="0 0 47 50">
	<!-- 長いので略 -->
 </symbol>
 <symbol id="egg" viewBox="0 0 47 50">
	<!-- 長いので略 -->
 </symbol>
</svg>

冒頭の <svg>要素の属性を整理します。(上記コードの1行目)
「名前空間宣言(xmlns="http://www.w3.org/2000/svg")」は必須です。無いと無理。
バージョンは無くても表示しましたが、一応残しました。
他の、サイズや位置に関する属性は、アイコンごとに指定するので削除しました。

「名前空間宣言」は、ブラウザに「このXMLはSVGだ」と宣言するもの。SVGはXML言語なので。
HTML5上に直接この<svg>を置く場合は「名前空間宣言」が無くても表示されますが、外部ファイルにするときは「名前空間宣言」がないとダメでした。画像が表示されません。
★<svg>要素の属性については [70-1] svg要素でベクターグラフィクスを埋め込もうをご覧ください。

ここではクラス名を入れていますが、これは後でCSSで「display:none」にするため。
(ここでジカに「style="display:none"」って書いてもOKです)display:none の理由は後で説明

<g>要素を<symbol>要素に書き換え、viewBox属性もここに

各アイコンのかたまりである <g>要素を <symbol>要素に書き換えます。

編集後のSVGファイル

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" class="allergen-icon">
 <symbol id="milk" viewBox="0 0 47 50">
	<!-- パスなどのコード。長いので略 -->
 </symbol>
 <symbol id="wheat" viewBox="0 0 47 50">
	<!-- 長いので略 -->
 </symbol>
 <symbol id="egg" viewBox="0 0 47 50">
	<!-- 長いので略 -->
 </symbol>
</svg>

<g id="milk"> 〜 </g> を、<symbol id="milk"> 〜 </symbol> にする、という要領です。
Illustratorでの描画時につけたアイコンの名前(レイヤー名)が id名になっているので、どの<g>要素かすぐ分かります。

さらに、<symbol id="milk" viewBox="0 0 47 50"> といったかんじで、冒頭の<svg>要素に入っていた viewBox属性を <symbol>要素に入れます。
(Illustratorで <svg>要素に書き出されていたものをコピペするだけです。数値は「0 0」は図形の基点、「47 50」は幅と高さ)

こうすることで 各アイコンは HTML上で好きなサイズにCSSで指定できるようになります。

<symbol>要素にする利点

<symbol>要素は、その名のとおり図形を「シンボル」にする要素。
複数のシンボルをまとめて1つのシンボルとして扱ったりもできます。
<symbol>要素の中身はそのままでは表示されず、<use>要素で呼び出すことで表示します。

<g>要素も <use>要素で呼び出して使うことができますが、
<symbol>要素の利点は viewBox属性を使えること。
viewBox属性を指定しておけば、呼び出したところで自由にサイズを変えられます
<g>要素ではviewBox属性が使えないので、<g>要素で指定したサイズが固定サイズになります。

HTML上に SVGファイルを呼び出す

出来上がった 外部SVGファイルを、HTMLの<body>直下に呼び出します。

呼び出すには 外部SVGファイルのパス(URL)を使います。
今回のサンプルではこのように「img」フォルダ内に外部SVGファイルを入れときました。

jQueryを使う方法

jQueryを使うので、先にjQueryを読み込むのを忘れずに。

以下のコードを <head>部に入れればOK。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
    <!--jqueryのバージョンは3系でもOK。古い1系でも使えました-->
<script>
  $.ajax({
    type: 'get',
    url: './img/allergen_icon.svg' <!--外部SVGファイルのパスを書きます-->
  }).done(function(data) {
    var svg = $(data).find('svg');
    $('body').prepend(svg); <!--<body>要素の先頭にSVGファイルが読み込まれます-->
  });
</script>
</body>

このJavaScriptコードは、こちらのサイトを参考にさせていただきました。ありがとうございます。
UNORTHODOX WORKBOOK|外部SVGファイルを非同期で読み込み、インラインのSVGスプライトとして利用する

こちらのサイトのように↑、JavaScriptは <body>内に書いてもOK。
私は jQueryは<head>部に置くことが多いので、どうせなら全部<head>部に入らないかなと、やってみたところ大丈夫でした。

PHPならたった1行

WordPressを使ってるサイトなら、PHPで簡単に外部SVGファイルを読み込めます。
PHPの「include_once( )」を使って <body>直下に1行を追加するだけ。
★WordPressだと include_once(" ") というカタチにするそうです。(かっこ内でダブルクォーテーションマークでファイル名を囲む)

WordPressの場合の外部SVGの読み込み

<body>
<?php include_once("images/allergen_icon.svg"); ?>
<!--ここでは外部SVGファイルは「images」フォルダに入れています-->

このコードを書くファイルは、<body>タグがあるファイル。たいてい「header.php」ですね。

で、外部SVGファイルのパスは相対パスで書くのがミソ。これ重要。
絶対パス(http://で始まるやつ)で書くと読み込まれませんでした。WordPressの仕様でしょうか。

例えば、上のサンプルコードの場合は、ファイルの位置関係はこのようになっています。

コードを書く「header.php」からの相対位置で、外部SVGファイル「allergen_icon.svg」を指定するのでパスは「images/allergen_icon.svg」になります。
「images」に入れず「header.php」と同じディレクトリなら、パスは「allergen_icon.svg」だけ。

外部SVGファイルの <svg>要素を display:none にする理由

上記の2つの方法(jQueryを使う方法・PHP)とも、外部SVGに書かれたコード(<svg> 〜 </svg>)が、HTML の <body>のすぐ下に書き出されます
でも各アイコンは<symbol>要素にしているので、そこでは図形は表示されない。
だけど、図形分のスペースは空くんです。なのでその分ごそっと下がってレイアウトが変になっちゃう。

そこで、外部SVG内の <svg>要素に display:none を指定しておくというわけです。display:none はスペースも詰めてくれます。

このように、外部SVGファイルの内容は <body>タグの直下に書き出されますので、WordPressの場合では全ページにコードが読み込まれることになります。(静的なHTMLの場合なら、読み込ませたHTMLファイルのみにSVGが書き出されます)
ですので「SVGスプライト」は、全ページ共通に使う図形(SNSアイコンとか)に限定すべき。
単一ページでのみ使う図形なら、SVGスプライトにしないで普通にSVGを貼り付けたほうが無難です。

SVG画像を使いたいところに<use>要素で呼び出す

次はいよいよ 各アイコンを HTML内で使っていきます。

SVGの図形を呼び出すには <use>要素を使います
<svg><use xlink:href="#id名"/></svg>というカタチで利用。この<svg>要素の位置に図形が表示されます。
id名は、各図形の <symbol>要素につけた id名です。

サンプルでは、下記のように書いています。

サンプルのHTML抜粋

<div>
 <h3>キッズハンバーグ<span>(乳・小麦・卵は使用しておりません)</span></h3>
 <svg class="al-icon"><use xlink:href="#milk"/></svg>
 <svg class="al-icon"><use xlink:href="#wheat"/></svg>
 <svg class="al-icon"><use xlink:href="#egg"/></svg>
</div>

呼び出すときは超シンプルなコードでOK。同じアイコンを何度でも呼び出せます。

サンプルでは各<svg>要素にクラス名(class="al-icon")をつけました。これはサイズなどを CSSで指定するため。

CSSでサイズなどを指定

各アイコンのサイズ指定などはCSSで行います。
サンプルのCSSは下記のようになっています。

svg.allergen-icon {display:none} /*SVGスプライト内のsvgを display:none にしておきます*/
svg.al-icon { /*HTML上に配置する各アイコンの指定です*/
    margin:0 10px 0 0;
    width:104px; /*サイズの指定(拡大になるけどキレイ)*/
    height:110px;
    padding:5px; /*paddingはドロップシャドウのために指定しています*/
    -webkit-filter: drop-shadow(2px 2px 2px #ccc); /*ドロップシャドウ(ちょっと古めのブラウザ用)*/
    filter: drop-shadow(2px 2px 2px #ccc)} /*ドロップシャドウ*/

各アイコンの元のサイズは 47×50pxです。CSSでのサイズ指定は拡大していますが、SVGなので拡大してもキレイです。
<symbol>要素には viewBox属性が使えるので、このように呼び出した後でサイズ変更ができます。

ドロップシャドウをつけることもできます(7、8行目)
これは CSS3の filterプロパティを使っています。(IE11は filterプロパティには未対応です)

サンプルの「drop-shadow(2px 2px 2px #ccc)」という「( )」内の4つの値は、
x方向のズレ y方向のズレ ぼかし幅 シャドウの色」です。
x, y方向のズレはマイナスの値も使えます。色指定は16進数指定じゃなくても何でもいけます。
色指定は [14-4] 色指定について(16進数, 色名, 10進数, HSL, accessibility)をご覧ください。

Chromeや Operaの場合、<svg>要素にドロップシャドウを指定しても、中身のSVGアイコンそのものにシャドウがつくので、それが<svg>要素にピッタリサイズになってる(<symbol>要素のviewBox属性のため)のでシャドウが見えなくなってしまいます。
それを防ぐために <svg>要素に paddingの指定をしました(6行目)。

次回予告

SVGについては、今回で終わりです。

時系列では次回から またCSSに戻ります。
displayプロパティが終わったところなので、次は visibilityプロパティをやろうと思っています。

時系列だと HTMLの話、CSSの話とあちこち飛んでわかりにくいですね。
インデックスから記事を選んでいただけますので、ご利用ください。
はじめてのHTML INDEX
はじめてのCSS INDEX

関連記事
このエントリーをはてなブックマークに追加

やる気を保つためにランキングに参加しています。
応援してくださると すっごいやる気を出します! (笑)

初心者にも使いやすい(と思う)レンタルサーバー

「初心者ですがレンタルサーバーはどこがいい?」というご質問をよくいただきます。
自由にファイルをアップロードできる自分のサーバがあると便利ですよね。ローカル環境じゃなくサーバ上で試してみたい時がありますからね。
私が使っているのは、 スターサーバーロリポップ!です。どちらも管理画面がわかりやすく、マニュアルも充実していて、料金も安い。どちらもライトプラン以上で WordPress が使えます。
初心者が始めやすいサーバだと思います。

ちょっと料金は高いけど、さくらのレンタルサーバや、エックスサーバー は、やはり老舗なのでおすすめです。
両方とも高スペックでコスパが良く、老舗でユーザーが多いので、質問する場がたくさんあります。初心者だけど仕事でサーバが欲しい場合は、安心なのではないかと思います。

スポンサーリンク

コメントの投稿

ご注意:メールアドレスは書かないで
「コメントを送信する」ボタンを押した後の「確認画面」で、メールアドレス・URL などを入力できるようになっており、メールアドレス・URL は、そのままオートリンクになる仕様です。
当方でメールアドレスだけ削除することも、メールアドレスを非公開にすることもできません
メールアドレスは書かないでください。詳しくはこちらにまとめましたのでご覧ください。

スポンサーリンク
最新記事
Category
オススメの本
Links
Calendar
11 | 2023/12 | 01
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 - - - - - -
Archive
Profile

yuki★hata

Author : yuki★hata
せめて月1回の更新をめざします~。

メールフォームはこちら

スポンサーリンク
スポンサーリンク
Copyright © ほんっとにはじめてのHTML5とCSS3 All Rights Reserved.