LoginSignup
9
6

More than 5 years have passed since last update.

gulp.spritesmithをレスポンシブに対応させる

Posted at

※注意
この記事で紹介しているのは
gulp-spritesmith
ではなくて
gulp.spritesmith
です。
紛らわしいので、間違えないようにご注意を。

sprite化は面倒くさい

既存のサイトでレスポンス速度向上のために、一部の画像をsprite化する運びになった。
自分で作成するのはだるいし、工数もかかるのでgulpを使って自動化できないかと思って、前に見た記憶を辿りながらたどり着いたのが
gulp.spritesmith
↑これ

sprite化したい画像を特定のディレクトリにポコポコ投げ入れて、taskを回すとsprite画像を作成してくれて、sassとかstylusとかlessとかに変数を吐き出してくれる。

こういう便利なものを作成してくれる人には頭が上がらない。
感謝....圧倒的感謝!

使い方

まずはinstall

$ yarn add gulp.spritesmith -D

taskを追加

gulpfile.js
gulp.task('sprite', () => {
    // pathの設定は適宜変えてくだしあ
    const spriteData = gulp.src('/path/to/sprite/*.png') // スプライト化したい画像を入れるディレクトリ
    .pipe(spritesmit({
        imgName         : '/path/to/img/contents-sprite.png', // sprite画像の名前
        imgpath         : '/path/to/img/contents-sprite.png', // sprite画像のpath
        cssName         : 'sprite.scss', // スプライト用のcssの名前
        cssFormat       : 'scss', // ファイルのフォーマット
        padding         : 5 // 画像のpadding
    }));
    spriteData.img.pipe(gulp.dest('./dest/path/to/sprite'));             // スプライト画像の出力先
    spriteData.css.pipe(gulp.dest('./src/path/scss/')); // スプライト用の scss ファイルの出力先
});

実行

実行すると、指定したパスの場所にcontents-sprite.pngっていうsprite化したい画像がひとまとまりになったファイルと、変数が格納されているsprite.scssっているscssファイルが作成される。

変数名は基本的に画像ファイルの名前に沿って作成される模様。
レスポンシブ対応とか考えてない場合は、そのまま@importするなりなんなりして、仕様すれば使えるはず。

レスポンシブ対応したい

このままでも仕様は出来るが、当たり前だが画像が等倍で表示されてしまう。
要素の'width'や'height'に対して目一杯画像を広げたいので、それ用のmixinを作成する。

作成される変数の中身はこんな感じ。

sprite.scss
$sprite-image-name: 'sprite-image';
$sprite-image-x: 445px;
$sprite-image-y: 45px;
$sprite-image-offset-x: -445px;
$sprite-image-offset-y: -45px;
$sprite-image-width: 10px;
$sprite-image-height: 20px;
$sprite-image-total-width: 459px;
$sprite-image-total-height: 391px;
$sprite-image-image: '/path/to/contents-sprite.png';
$sprite-image: (445px, 45px, -445px, -45px, 10px, 20px, 459px, 391px, '/path/to/contents-sprite.png', 'sprite-image', );

// ~ 中略 ~

@mixin sprite-width($sprite) {
  width: nth($sprite, 5);
}

@mixin sprite-height($sprite) {
  height: nth($sprite, 6);
}

@mixin sprite-position($sprite) {
  $sprite-offset-x: nth($sprite, 3);
  $sprite-offset-y: nth($sprite, 4);
  background-position: $sprite-offset-x  $sprite-offset-y;
}

@mixin sprite-image($sprite) {
  $sprite-image: nth($sprite, 9);
  background-image: url(#{$sprite-image});
}

@mixin sprite($sprite) {
  @include sprite-image($sprite);
  @include sprite-position($sprite);
  @include sprite-width($sprite);
  @include sprite-height($sprite);
}

@mixin sprites($sprites) {
  @each $sprite in $sprites {
    $sprite-name: nth($sprite, 10);
    .#{$sprite-name} {
      @include sprite($sprite);
    }
  }
}

レスポンシブ対応させるためのmixinを作成する

_sprite-responsive.scss
@charset "UTF-8";

// 変数が入っているscssをimport
@mixin sprite-responsive($sprite){
    $sheet-w    : nth($sprite, 7);
    $sheet-h    : nth($sprite, 8);
    $sprite-w   : nth($sprite, 5);
    $sprite-h   : nth($sprite, 6);
    $offset-x   : nth($sprite, 1);
    $offset-y   : nth($sprite, 2);
    $bg-path    : nth($sprite, 9);

    // テキストを隠す
    white-space: nowrap;
    text-indent: 100%;
    overflow: hidden;
    font-size: 0;

    background-image: url($bg-path);
    background-size: ($sheet-w / $sprite-w * 100 + 0%) ($sheet-h / $sprite-h * 100+ 0%);
    background-position: ($offset-x / ($sheet-w - $sprite-w) * 100 + 0%) ($offset-y / ($sheet-h - $sprite-h) * 100 + 0%);

    &:after{
        content: '';
        display: block;
        padding-top: ($sprite-h / $sprite-w * 100 + 0%);
    }

}

nth($sprite, number)$spriteのリストにアクセスしている。
(この機能知らなかった...)

参考:
HAIL2U.NET
sassのnth()関数

background-imageとかで演算式の後に+ 0%と記述しているのは単位を%にするため。
(他に良い方法が見つからなかった orz)

で、あとはこのファイルの以下に@includeして書いていく感じ。

_sprite-responsive.scss

i.sprite{
    @include sprite-responsive($sprite-image);
    display: inline-block;
    width: 6px;
    height: 12px;
}

これで指定したwidthheightの中にちょうど良く収まってくれる...はず。

修正等があれば、書き直します。

9
6
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
6