楽ちんカスタム!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要素ごとに呼び出しています。






#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. メモからはじめる情報共有 DocBase 無料トライアルを開始
  2. DocBase 資料をダウンロード

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

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

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

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


トラックバック

we use!!Ruby on RailsAmazon Web Services

このページの先頭へ