使用compass自动拼css sprite

Posted on 2015-10-24 in SASS by yucongchen

css sprite (css 雪碧)又叫css精灵,是一种图片拼合技术。多用在图标上,把几个图标拼成一个图片,页面加载的时候只需要load拼好的图片,然后使用background-position配合width、height来显示不同的图标。这样做可以减少页面请求数。但是,想想把一个个图标从psd上扣下来,合到一个图上,然后还要慢慢算background-position,这也真是醉了,而且后期如果改了图标,又要重新拼一次,拼完再算一次background-position,真是坑大了。

对于这种耗时的体力活,都应该自动化。本文就介绍使用compass来自动拼css sprite。

安装compass

这里安装和配置可以参考我另外一篇文章,SASS用法介绍,这里就不多做介绍了。compass经常配合sass使用,推荐平常用sass,提高写css的效率。


合成css sprite

首先我们对config.rb文件进行一些改动:

# Get the directory that this configuration file exists in
dir = File.dirname(__FILE__)

#Compass configuration
sass_path = dir
css_path = File.join(dir, "..", "css")
images_dir = "../img"
environment = :production # :development # :production
output_style = :compact # :expanded # :compressed

这里主要是加了image_dir这一项。 然后我们添加一个sass文件tmp.scss:

@import "compass/utilities/sprites";    
@import "tmp/*.png";                    
@include all-tmp-sprites; 

这里第一行是加载compass的sprites模块。 第二行表示把tmp目录下所有的png文件拼起来,这里的tmp是一个相对目录,如果没有配置sprite_load_path这一项的话,默认就会使用我们刚才加的images_dir这一项,实际上,如果连这一项也没配置也不怕,默认叫images。这里要特别说明一下,以我们现在的配置文件来说,需要一个tmp目录,放到img目录下,tmp目录里面放的就是我们需要拼接的图片。 第三行的话,意思是输出所有sprite的css,也就是计算好的background-position。这里中间的tmp需要和上面一样,如何修改需要查阅文档。

之后调用compass compile进行编译,发现img目录下出现了一个拼接后的图片tmp-sxxxxxxxxxx.png,然后css目录下生成了对应的tmp.css文件。


图片命名优化

是不是觉得自动生成图片爽爽的,但是带了一大串hash数字在图片名中很不舒服。下面我们就来处理这段数字。

compass提供了一些钩子函数,compass里面叫callback,这里我们用到一个叫on_sprite_saved的钩子。在config.rb文件中添加下面这段,注意如果是用compass watch来自动检测改动的话,需要中断,重新运行compass watch

on_sprite_saved do |filename|
  if File.exists?(filename)
    FileUtils.cp filename, filename.gsub(%r{-s[a-z0-9]{10}\.png$}, '.png')
  end
end

重新run之后,发现多了一个tmp.png文件,而原来带hash的文件也还在,其实因为用的是FileUtils.cp函数,所以做的是copy,如果改成FileUtils.mv则不会有带hash值得文件。 然后再看一下tmp.css文件,发现里面还是用的是带hash的那个文件。 这里还要用另外一个钩子:

on_stylesheet_saved do |filename|
  if File.exists?(filename)
    css = File.read filename
    File.open(filename, 'w+') do |buffer|
      buffer << css.gsub(%r{-s[a-z0-9]{10}\.png}, '.png')
    end
  end
end

ok,大功告成。

完整的config.rb:

# Get the directory that this configuration file exists in
dir = File.dirname(__FILE__)

#Compass configuration
sass_path = dir
css_path = File.join(dir, "..", "css")
images_dir = "../img"
environment = :production # :development # :production
output_style = :compact # :expanded # :compressed

on_sprite_saved do |filename|
  if File.exists?(filename)
    # FileUtils.cp filename, filename.gsub(%r{-s[a-z0-9]{10}\.png$}, '.png')
    FileUtils.mv filename, filename.gsub(%r{-s[a-z0-9]{10}\.png$}, '.png')
  end
end

on_stylesheet_saved do |filename|
  if File.exists?(filename)
    css = File.read filename
    File.open(filename, 'w+') do |buffer|
      buffer << css.gsub(%r{-s[a-z0-9]{10}\.png}, '.png')
    end
  end
end

compass还有很多配置选项,可以参考官网传送门,或者这篇文章


参考

http://riny.net/2014/compass-sprite/ http://segmentfault.com/q/1010000000308179 http://compass-style.org/help/documentation/configuration-reference/