こんちは。はっちゃんです。
みなさんは、iconってどうやって管理してますか?
iconfont化して使ってますか?
png画像単体で使ってますか?
pngのsprite画像で使ってますか?
svg単体で使ってますか?
自分はiconfont一点張りだったんですが、LIGのフロントエンドの中では「元のSVGファイルの管理がしづらいから『SVG sprite』を使ってる」って声がちらほら聞こえるので、今回はそのSVG spriteを本腰入れて使ってみたいと思います。
使い方
SVG spriteの使い方は下記の記事が詳しいので、載っている部分はさらっと流します。
https://design.dena.com/engineering/svg-sprite
今回、上記記事と異なる部分は以下になります。
-
- ディレクトリ構成
- svg-spriteのglobalインストールなし
- package.jsonでモジュール管理
- npm runコマンドを使用
また、nodeのバージョンは8.9.1を。
npmのバージョンは5.6.0を使用します。
ディレクトリ構成
このようなディレクトリ構成でやっていきます。
project
├── src
│ └── assets
│ └── svg-sprite
│ ├── facebook.svg
│ ├── line.svg
│ └── twitter.svg
├── assets
│ └── css
│ └── style.css
├── index.html
├── config.json
└── package.json
package.jsonの中身
{
"name": "svg-sprite-test",
"version": "0.1.0",
"description": "svg sprite test",
"devDependencies": {},
"scripts": {
“svgsprite" :"svg-sprite -C config.json —shape-transform-svgo svgo.json src/assets/svg-sprite/*svg"
},
"private": true
}
config.json
{
"dest": "assets",
"mode": {
"symbol": {
"dest" : "svg-sprite",
"sprite": "svg-spritesprite.svg"
}
}
}
svgo.json
{
"plugins": [
{ "removeTitle": true },
{ "removeAttrs": { "attrs": ["fill", "id", "data-name"] }}
]
}
※idを記載している理由は、最終的にSVG spriteがファイル名をidに付与してくれるから。不要なidを削除して、必要なidだけ残すことができます。
動かしてみる
それではさっそく動かして行きましょう。
svg spriteをインストール
npm i svg-sprite —save-dev
package.jsonに書いたsvgspriteコマンドを実行
npm run svgsprite
assets/svg/にsvg-sprite.svgが出力されているかと思います。
backgroundで使用するSVG spriteの書き出し方法
config.jsonとは別にconfig-bg.jsonを用意します。
config-bg.json
{
"dest": "assets",
"mode": {
"css": {
"dest": "svg-sprite-bg",
"sprite": "sprite-sprite-bg.svg",
"bust": false,
"render": {
"css": {
"dest": “../css/svg-sprite-bg.css"
}
}
}
}
}
src/svg-sprite-bg/の中に、3つのsvgファイルを名前を変えて置いておきます。
- facebook-bg.svg
- line-bg.svg
- twitter-bg.svg
最後にsvgspriteコマンドを下記のように修正します。
"scripts": {
"svgsprite": "svg-sprite -C config.json —shape-transform-svgo svgo.json src/assets/svg/*svg && svg-sprite -C config-bg.json --shape-transform-svgo svgo.json src/assets/svg-bg/*.svg"
}
実行
npm run svgsprite
assets/svg-sprite-bg配下にsvg-sprite-bg.svg
assets/css配下にsvg-sprite-bg.css
が書き出されているかと思います。
最終的なディレクトリ構成は下記になります。
project
├── src
│ └── assets
│ └── svg-sprite
│ ├── facebook.svg
│ ├── line.svg
│ └── twitter.svg
│ └── svg-sprite-bg
│ ├── facebook-bg.svg
│ ├── line-bg.svg
│ └── twitter-bg.svg
├── assets
│ └── css
│ └── style.css
│ └── svg-sprite-bg.css
├── index.html
├── config.json
├── config-bg.json
└── package.json
HTML、CSSを書いてみる
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<link href="./assets/css/style.css" rel="stylesheet">
<link href="./assets/css/svg-sprite-bg.css" rel="stylesheet">
</head>
<body>
<section>
<h2>インラインで使用</h2>
<div class="row">
<div class="grid">
<div class="grid-item">
<div class="svg-facebook">
<svg class="svg-sprite" role="img">
<use xlink:href="./assets/svg-sprite/svg-sprite.svg#facebook" xmlns:xlink="http://www.w3.org/1999/xlink"></use></svg>
</div>
</div>
<div class="grid-item">
<div class="svg-twitter">
<svg class="svg-sprite" role="img">
<use xlink:href="./assets/svg-sprite/svg-sprite.svg#twitter" xmlns:xlink="http://www.w3.org/1999/xlink"></use></svg>
</div>
</div>
<div class="grid-item">
<div class="svg-line">
<svg class="svg-sprite" role="img">
<use xlink:href="./assets/svg-sprite/svg-sprite.svg#line" xmlns:xlink="http://www.w3.org/1999/xlink"></use></svg>
</div>
</div>
</div>
</div>
</section>
<section>
<h2>backgroundで使用</h2>
<div class="row">
<div class="grid-bg">
<div class="grid-item-bg">
<div class="svg-facebook-bg svg-facebook-bg-dims"></div>
</div>
<div class="grid-item-bg">
<div class="svg-twitter-bg svg-twitter-bg-dims"></div>
</div>
<div class="grid-item-bg">
<div class="svg-line-bg svg-line-bg-dims"></div>
</div>
</div>
</div>
</section>
<script src="./assets/js/svg4everybody.min.js"></script>
<script src="./assets/js/app.js"></script>
</body>
</html>
style.css
section ~ section {
margin-top: 60px;
}
.row {
padding: 0 20px;
}
.grid {
display: flex;
justify-content: center;
margin-left: -20px;
margin-right: -20px;
}
.grid-item {
padding: 0 20px;
}
.grid-bg {
display: flex;
justify-content: center;
margin-left: -150px;
margin-right: -150px;
}
.grid-item-bg {
margin-top: 80px;
padding: 0 150px;
}
.svg-facebook .svg-sprite {
fill: #3c599b;
}
.svg-twitter .svg-sprite {
fill: #2aa3f0;
}
.svg-line .svg-sprite {
fill: #1bb91f;
}
.svg-facebook-bg {
transform: scale(4.5);
}
.svg-twitter-bg {
transform: scale(4.5);
}
.svg-line-bg {
transform: scale(4.5);
}
svg-sprite-bg.cssは下記のように出力されているのでそのまま使います。
.svg-facebook-bg {
background: url("../svg-sprite-bg/svg-sprite-bg.svg") 100% 0 no-repeat;
}
.svg-facebook-bg-dims {
width: 32px;
height: 32px;
}
.svg-line-bg {
background: url("../svg-sprite-bg/svg-sprite-bg.svg") 0 100% no-repeat;
}
.svg-line-bg-dims {
width: 32px;
height: 32px;
}
.svg-twitter-bg {
background: url("../svg-sprite-bg/svg-sprite-bg.svg") 0 0 no-repeat;
}
.svg-twitter-bg-dims {
width: 40px;
height: 32px;
}
実際に表示してみる
GitHubに公開しました。
https://82mou.github.io/svg-sprite/
まだ自分の中で納得がいっていないのが、backgroundで読み込んでいるSVG spriteのサイズを簡単に管理する方法です。コンパイルで自動で出力されるCSSには、原寸のサイズが記載されています。
実際に案件で使うときは、場所によってはサイズを調整しなければいけないので、background-sizeとwidth、heightを修正する必要があります。
ただ、動的に出力されるCSSの修正はできないので、今回はstyle.cssの方で、transformのscaleで大きさを調整しています。
配置はpaddingで画面見ながら調整したので、この辺をもう少しスマートにできたらいいですね……。
まとめ
いかがでしたか?
IE用にpolifillを入れないと使えませんが、idでひとつひとつのSVGを呼び出せるし、使い勝手はそんなに悪くないです。backgroundでもなんとか動かすことができるので、これからはSVG spriteをスタンダードで使っていきたいと思います。
LIGはWebサイト制作を支援しています。ご興味のある方は事業ぺージをぜひご覧ください。