楽ちんカスタム!RailsでSVGスプライトを使おう このエントリをはてなブックマークに登録

2016年10月12日

asachunasachun

こんにちは、にわかカープファンの亀井です。先日マツダスタジアムに観戦に行ったら私の応援がうるさすぎたのか隣に座ったおじいさんがいつのまにか移動していました。

最近はIE8以下の対応も減り、気軽にSVG画像を使えるようになってきたのではないでしょうか?クレイでも出来る限りアイコンなどはSVG画像にしているので、今回はRailsでの使い方をご紹介します。※弊社では主にテンプレートエンジンにHaml, Sassを使っているので、説明でもHaml, Sassを使います。

SVGの読み込み方

SVGは様々な読み込み方がありますが、最近は私はほぼインラインSVGです。
理由としては

  1. CSSで色や線などのスタイルを変更できる
  2. 使い回しが容易
  3. Sourceの読み込み数が減るのでサイトが軽くなる

特に 1. の理由が大きいです。PNGの場合、同じ形でも色が違えば違う画像として書き出す必要がありますが、SVGであれば同じSVG画像を使ってCSSで色だけ変更することができるからです。とてもDRY!

詳しいことは私のブログのSVGのオブジェクトごとにCSSで色を切り替えるに書いておりますのでご参照ください(個人ブログで恐縮です)。

a7a41146-21eb-4578-bdaf-a64f376e84cc

SVGスプライトの作成

npmでSVGスプライトを作成できるツールはいくつかありますが、弊社ではnpmを導入していないプロジェクトもあるのでGemのSvgeezを使います。

Svgeezのインストール

Gemfileに以下を追加し、 bundle install します。


gem 'svgeez'

スプライトしたいSVG画像を任意のディレクトリに格納

こちらでは app/assets/images/svg に格納します。ディレクトリの名前はなんでも大丈夫です。

注意点

  • SVGのオブジェクトにfill属性などが指定されているとCSSでの色の変更ができなくなりますので削除しておきましょう。
  • SVG内でStyleをclassで指定されている場合がありますが、IllustratorやPhotoshopで書き出すとclass名が被ってしまいスタイルがおかしくなることがあります。削除するかclassを使わない形に書き直しておきましょう。

Svgeezを実行

RailsプロジェクトのROOTで以下のコマンドを実行します。


svgeez build -s app/assets/images/svg -d app/assets/images/icons.svg

app/assets/images/icons.svg が作成されたSVGスプライトです。こちらをHamlに読み込みます。

作成したSVGスプライトを読み込む

%body の最後に以下のコードを記述します。

Rails 4.2, 5 (sprockets-rails 3) の場合 


= raw Rails.application.assets_manifest.find_sources('icons.svg').first

Rails 4.0, 4.1 (sprockets-rails 2)の場合  


= raw Rails.application.assets.find_asset('icons.svg')

app/assets/images/svg に格納されていたSVG画像のひとつひとつはSymbol要素としてicons.svgに書き込まれています。

補足

以前、SvgeezのドキュメントではRails 4.1以前の読み込み方法しか書いていなかったのですが、Rails 4.2以降 (sprockets-rails 3) からconfig.assets.compileがfalseの時にRails.application.assetsはnilになるので find_assetは使えませんでした(config.assets.compileはproduction環境ではfalseにしている場合が多いため)。ですがダニーさんが直接Pull Requestを出してくれたので、Rails 4.2以降の読み込み方法がドキュメントに追加されました。ダニーさんに感謝 pray

SVGを使う

SVG内のuse要素にて目的のsymbolを呼び出します。IDでの指定なので # が必要です。


%svg
  %use(xlink:href="#icons-hoge")

SVGスプライトにする前のSVGのファイル名がID名になります。デフォルトではSvgeezにより icons- プレフィクスがつくので、例えば hoge.svg という名前だった場合 #icons-hoge となります。

注意点
# を付け忘れて表示されない…ということがわりとあるので気をつけましょう。Helperを作ってもいいですね。

実際の仕様例

弊社で絶賛開発中のDocBaseでもSVGスプライトを使用しています。DocBaseでは LightDark の2つのデザインテーマが選べるようになっていますが、テーマによってアイコンの配色が違うのでSVGを使用しCSSで色を変更しています。

Lightテーマ
スクリーンショット_2016-09-30_12_11_01.png

Darkテーマ
スクリーンショット_2016-09-3
![スクリーンショット 2016-09-30 12.07.33.png](https://image.docbase.io/uploads/7c498eb5-fea1-4d50-abcc-ba82d908e572.png)
0_12_11_40.png

使用しているのはサイドメニューのアイコンです。
スクリーンショット 2016-09-30 12.06.57.png スクリーンショット_2016-09-30_12_07_33.png

アイコン部分のソースは以下のようになっています。


%svg.nav-list__item-icon.-type-group
  %use.nav-list__item-icon-back(xlink:href="#icon-group__back")
  %use.nav-list__item-icon-front(xlink:href="#icon-group__front")

use要素が2つありますが、こちらはCSSで操作するためSVG側で色を変えたい要素をg要素で囲み、そのg要素ごとに呼び出しています。

<symbol id="icon-group" viewBox="0 0 18 13">
  <g id="icon-group__back">
    <path d="M14.400,9.506 C12.939,8.711 11.479,8.023 11.006,7.895 C10.297,7.701 10.232,7.336 10.877,6.197 C11.436,5.187 11.650,2.373 11.113,1.320 C10.748,0.525 9.846,-0.012 8.879,-0.012 C8.600,-0.012 8.299,0.031 7.998,0.139 C6.537,0.697 6.215,1.836 6.236,3.512 C6.258,4.543 6.473,5.531 6.666,5.854 C7.482,7.314 7.396,7.766 6.666,7.916 C6.129,8.023 4.152,8.969 3.186,9.592 C1.939,10.408 1.424,12.127 2.369,12.363 C2.605,12.428 5.914,12.492 9.072,12.492 C11.865,12.492 14.572,12.471 15.002,12.406 C15.689,12.320 15.711,12.299 15.754,11.762 C15.818,10.881 15.303,10.000 14.400,9.506 ZM2.713,8.861 C3.379,8.453 4.668,7.744 5.613,7.357 C5.377,7.250 5.205,7.164 5.119,7.143 C4.732,7.035 4.668,6.863 5.012,6.197 C5.312,5.639 5.463,4.092 5.184,3.490 C4.904,2.910 4.131,2.588 3.443,2.846 C2.627,3.125 2.434,3.770 2.455,4.715 C2.455,5.295 2.584,5.854 2.691,6.025 C3.164,6.842 3.078,7.078 2.691,7.164 C2.391,7.229 1.295,7.766 0.758,8.109 C0.049,8.539 -0.252,9.527 0.285,9.656 C0.350,9.678 0.973,9.699 1.789,9.699 C2.047,9.398 2.369,9.098 2.713,8.861 ZM16.850,8.045 C16.033,7.615 15.217,7.229 14.959,7.143 C14.594,7.035 14.551,6.863 14.894,6.197 C15.195,5.639 15.303,4.092 15.023,3.490 C14.766,2.910 13.992,2.588 13.283,2.846 C12.467,3.125 12.295,3.770 12.316,4.715 C12.316,5.295 12.467,5.854 12.553,6.025 C13.025,6.842 12.961,7.078 12.553,7.164 C12.467,7.186 12.273,7.250 12.059,7.336 C12.853,7.680 13.928,8.238 14.809,8.754 C15.281,8.990 15.668,9.334 15.947,9.699 C16.592,9.699 17.086,9.678 17.193,9.656 C17.580,9.613 17.580,9.592 17.602,9.291 C17.645,8.797 17.365,8.324 16.850,8.045 Z" fill-rule="evenodd"/>
  </g>
  <g id="icon-group__front">
    <path d="M14.400,9.506 C12.939,8.711 11.479,8.023 11.006,7.895 C10.297,7.701 10.232,7.336 10.877,6.197 C11.436,5.187 11.650,2.373 11.113,1.320 C10.748,0.525 9.846,-0.012 8.879,-0.012 C8.600,-0.012 8.299,0.031 7.998,0.139 C6.537,0.697 6.215,1.836 6.236,3.512 C6.258,4.543 6.473,5.531 6.666,5.854 C7.482,7.314 7.396,7.766 6.666,7.916 C6.129,8.023 4.152,8.969 3.186,9.592 C1.939,10.408 1.424,12.127 2.369,12.363 C2.605,12.428 5.914,12.492 9.072,12.492 C11.865,12.492 14.572,12.471 15.002,12.406 C15.689,12.320 15.711,12.299 15.754,11.762 C15.818,10.881 15.303,10.000 14.400,9.506 Z" fill-rule="evenodd"/>
  </g>
</symbol>

#icon-group__back#icon-group__front はこんなかんじで分かれています。

スクリーンショット-2016-09-30-12.32.57.png

そちらをテーマごとにスタイルを変えています。

light.sass


body.-theme-light
  .nav-list
    &__item-icon.-type-group
      .nav-list__item-icon-back, .nav-list__item-icon-front
        fill: #5692ce

dark.sass


body.-theme-dark
  .nav-list
    &__item-icon.-type-group
      .nav-list__item-icon-back
        fill: #fff
      .nav-list__item-icon-front
        fill: #5692ce

注意点
使うときのサイズが作成したSVGのサイズと違うと表示領域がおかしくなるので、その場合は呼び出し先のSVG要素にViewBox属性をつけてください。

これ、PNGでやろうと思ったらRetinaディスプレイ対応含めたら4つ画像作らないといけないですからね。SVGだったらひとつでOK wink 色の変更も一瞬でできます +1

宣伝

ee6e67ba-057d-4e4d-b994-ceb1969f7228

DocBaseとは

情報共有を活発にし、チームを育てるをコンセプトにした情報共有サービスです。柔軟な権限設定と使いやすさ、社内の人も社外の人も全員を招待できるから、さまざまな人やツールに散らばっていた情報を一元化できます。積極的な情報共有と業務の効率化を実現し、チームの成長を促します。

詳しくはこちらから。
DocBase

関連記事

クレイについてもっと知りたい方は…

  1. クレイの3つの強みを見てみる。
  2. WEBシステムのことなら何でもご相談ください。

「いいね!」で応援よろしくお願いします!

このエントリーに対するコメント

コメントはまだありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


トラックバック

we use!!Ruby on RailsAmazon Web Services

このページの先頭へ