@whileを使用して連番画像を書き出す

scssを学ぶ

記事の対象者

  • scssを使っている
  • ループ処理をしたい
  • 簡単なプログラミングを読める&書ける
    • (言語は問いません。基本的な式の書き方、代入方法、引数の概念などを理解している。)

環境

  • Scss
  • Pug

したいこと

  • 連番がつけられている画像を順に、指定回数表示したい。
  • 連番の番号範囲は都度指定したい。
    • Ex. img_05.pngimg_10.pngを表示など
  • 画像はbackgroundで表示
  • 要素に個別のクラスはつけず、nth-childを使用して指定する。

scssの繰り返しについて

scssの連番に関して検索をかけると、@for@eachでの書き方がまずでてきます。 連番の画像を指定回数出力したいだけ、などであればそれで十分なんですよね。

@for

繰り返しの処理ができます。

画像を指定回数出力したい場合、@forを使ってスタート値とエンド値を指定してあげればokです。

$font_min: 10;
$font_max: 15;
@for $i from $font_min through $font_max {
  .img_#{$i} {
    background-image: url("img_#{$i}.jpg");
  }
}

コンパイル

img_10classからimg_15classまでが書き出されています。

.img_10 {
  background-image: url("img_10.jpg");
}

.img_11 {
  background-image: url("img_11.jpg");
}

.img_12 {
  background-image: url("img_12.jpg");
}

.img_13 {
  background-image: url("img_13.jpg");
}

.img_14 {
  background-image: url("img_14.jpg");
}

.img_15 {
  background-image: url("img_15.jpg");
}

これはわかりやすいですね。

@each

配列を使いたい場合は@eachを使用します。 以下はクラス名に合わせて背景色を変える例です。

$colors: red, blue, yellow, green, black;

@each $color in $colors {
  .#{$color}-bg {
    background-color:#{$color};
  }
}

コンパイル

.red-bg {
  background-color: red;
}

.blue-bg {
  background-color: blue;
}

.yellow-bg {
  background-color: yellow;
}

.green-bg {
  background-color: green;
}

.black-bg {
  background-color: black;
}

こちらもわかりやすい。

@while

今回使用するのはこの@whileです。

@forより複雑な処理が可能です。

先ほど@forを使って書いた処理と同じ処理を@whileで記述してみます。

$font_min: 10;
$font_max: 15;
$img_i:$font_max - $font_min;
$var: 0;
@while $var <= $img_i {
  .img_#{$font_min} {
    background-image: url("img_#{$font_min}.jpg");
  }
  $font_min : $font_min + 1;
  $var: $var + 1; 
}

コンパイル

@forの時と同じ結果が出力されています。

.img_10 {
  background-image: url("img_10.jpg");
}

.img_11 {
  background-image: url("img_11.jpg");
}

.img_12 {
  background-image: url("img_12.jpg");
}

.img_13 {
  background-image: url("img_13.jpg");
}

.img_14 {
  background-image: url("img_14.jpg");
}

.img_15 {
  background-image: url("img_15.jpg");
}

@whileと@ifを使用して少し複雑な繰り返し処理をする

これまでのように簡単なものであれば@forを使用するのが良いかと思います。今回は@whileで指定回数コードを出力、さら画像はゼロパディングを使用して管理していますので、@ifで1〜9までは先頭に0をつける処理をします。

前提

  • 画像は5〜10を表示。
  • 要素に個別のクラス名はつけず、nth-childで対応する。

完成コード

$num:"";
$start_num : 5;
$end_num: 10;
$nth_num: 1;
$img_num:$end_num - ($start_num - 1);
@while $nth_num <= $img_num {
      @if $start_num < 10 {
         $num: "0#{$start_num}";
      } @else {
        $num: $start_num;
      }
  .sample:nth-child(#{$nth_num}) {
        background-image: url("img_#{$num}.jpg");
        } 
  $nth_num: $nth_num + 1; 
  $start_num :$start_num + 1;
}

コンパイル

.sample:nth-child(1) {
  background-image: url("img_05.jpg");
}

.sample:nth-child(2) {
  background-image: url("img_06.jpg");
}

.sample:nth-child(3) {
  background-image: url("img_07.jpg");
}

.sample:nth-child(4) {
  background-image: url("img_08.jpg");
}

.sample:nth-child(5) {
  background-image: url("img_09.jpg");
}

.sample:nth-child(6) {
  background-image: url("img_10.jpg");
}

.sample:nth-child(7) {
  background-image: url("img_11.jpg");
}

.sample:nth-child(8) {
  background-image: url("img_12.jpg");
}

解説

変数定義

以下の部分の解説です。

$num:"";
$start_num : 5;
$end_num: 10;
$nth_num: 1;
$img_num:$end_num - ($start_num - 1);

1.この後数値を代入するために空の$numを定義。

$num:"";

2.画像の連番の範囲を指定。今回は05〜10を指定します。

$start_num : 5;
$end_num: 10;

3.nth-childの数値を指定。 今回はnth-child(1)から指定回数まで繰り返そうと思います。

$nth_num: 1;

4.画像を何度出力するかの式 今回は10-(5-4)=6回です。

$img_num:$end_num - ($start_num - 1);

@whileの中身

以下の部分の解説です。

@while $nth_num <= $img_num {
      @if $start_num < 10 {
         $num: "0#{$start_num}";
      } @else {
        $num: $start_num;
      }
  .sample:nth-child(#{$nth_num}) {
        background-image: url("img_#{$num}.jpg");
        } 
  $nth_num: $nth_num + 1; 
  $start_num :$start_num + 1;
}

1.指定した数値になるまで繰り返す

$img_numは6、$nth_numは1が入ります。 6回まで処理を繰り返します。

@while $nth_num <= $img_num {

2.@if

10より画像の連番数が小さい場合は先頭に0が付く処理をします。

@if $start_num < 10 {
         $num: "0#{$start_num}";
      } @else {
        $num: $start_num;
}

3.書き出すコードを記述

初期状態では$nth-numには1、$numには05が入っています。

.sample:nth-child(#{$nth_num}) {
      background-image: url("img_#{$num}.jpg");
} 

4.繰り返す度に数値をプラスしていく処理を記述

$nth_num: $nth_num + 1; 
$start_num :$start_num + 1;

以上です。

もっとわかりやすい書き方があると思うのでまた思いついたら追記します。

この方が良いよ!という書き方があればお教えいただけると嬉しいです。

codepenの方には視覚的にも極力わかりやすくなるように、実際に実装したものとは違うコードを載せておきます。 (直リンク可能な連番画像の用意が面倒ということもある)

指定回数以上のはスタイルが適用されていないこともわかるかと思います。

See the Pen While文を使って連番を書き出す(ゼロパディング) by soto-ogre (@soto-ogre) on CodePen.