LoginSignup
9
9

More than 5 years have passed since last update.

Rails4でCompassのsprite-mapを利用しつつ、対応するcssをファイル名で自動で生成してみる

Last updated at Posted at 2014-03-10

環境

rails (4.0.2)
compass (0.12.2)
compass-rails (1.1.2)
sass (3.2.14)
sass-rails (4.0.1)

sprite対象のpng画像を配置

利用箇所毎にsprite画像を分けられるようにフォルダで分けておく

app/assets/images/sprites/common/icon_foo.png
app/assets/images/sprites/common/icon_bar.png
app/assets/images/sprites/home/btn_foo.png
app/assets/images/sprites/home/btn_bar.png

Retina対応のsprite画像を作る

application.sass
@import "compass/utilities"
@import "compass/css3"

// Retina対応sprite画像cssのmixin
@mixin sprite-background($name, $sprites, $sprites-image)
  background-image: $sprites-image
  background-repeat: no-repeat
  overflow: hidden
  display: inline-block
  width: image-width(sprite-file($sprites, $name)) / 2
  height: image-height(sprite-file($sprites, $name)) / 2
  $xpos: round(nth(sprite-position($sprites, $name), 1) / 2)
  $ypos: round(nth(sprite-position($sprites, $name), 2) / 2)
  background-position: $xpos $ypos
  $wbgz: image-width(sprite-path($sprites)) / 2
  @include background-size($wbgz auto)

// $nameを利用したクラス名のcssを作る部分
@mixin sprite-css($name, $sprites, $sprites-image)
  .#{$name}
    @include sprite-background($name, $sprites, $sprites-image)

各画像のcssをファイル名から生成

sassから指定したフォルダにおいてある画像名を取得処理(SassFunctionの拡張)
(file_namesをsortせずにいたらサーバ毎に違うハッシュのapplication.cssが作成されてハマった)

config/initializers/sass_functions.rb
module Sprockets::SassFunctions
  module CustomSassFunctions
    def sprite_image_names(path)
       file_names = Pathname.glob(Rails.root.join("app/assets/images", path.value)).collect{|f|f.basename(".*").to_s}
      Sass::Script::List.new(file_names.sort.map{|v| Sass::Script::String.new(v)}, :comma)
    end
  end
  include CustomSassFunctions
end

sass側から上記functionでファイル名のSass::Script::List配列を取得してeachしてsprite画像と各画像のcssを生成

application.sass
// sprite画像を生成した後、
// Rails側に用意したsass_functionを呼び出して該当フォルダの画像ファイル名を取得してファイルに応じたcssを作成する
$folders: common, home
@each $folder in $folders
  $path: "sprites/" + $folder + "/*.png"
  $sprites: sprite-map($path, $layout: smart)
  $sprites-image: sprite-url($sprites)
  @each $name in sprite_image_names($path)
    @include sprite-css($name, $sprites, $sprites-image)

実際に利用する場合ファイル名がそのままclass名になっている

<span class="icon_foo"></span>
<span class="icon_bar"></span>
<span class="btn_foo"></span>
<span class="btn_bar"></span>

cssのクラス名にフォルダ名も含めたほうがいいかもしれない

参考にさせてもらったサイト

http://qiita.com/good_flat/items/2bd9a37d450272562836
http://cappee.net/coding/sass-scss/sprite-path

9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9