SassでClass名を連番で書く方法(@for構文と@if構文)

はじめに

例えば.test001.test002.test099.test100のように同じクラス名で数字のみ連番で変えたい時、Sassのループ(繰り返し)処理を使うとCSS(SCSS)記述を簡略化できます。

ループ処理をするには@forを使うのですが、その使い方を紹介します。

目次

@forの使い方

Sassでループ処理をしたい場合、@forを使用します。

例えば.text001.text002.text009までのクラスを作りたい場合は、以下のようなSassの記述になります。

Sass

  1. @for $number from 1 through 9 {
  2.  .test00#{$number} {
  3.  ***** /*任意のプロパティ*/
  4. }

簡単な手順としては、まず変数(この場合では$number)を設定します。

次に、@for構文のfromの後ろに開始の値を入れthroughの後ろに終了する値を入れます。

最後に、変数「$number」を代入させるように.test00#{$number}とクラス名を記述します。

これをCSSにコンパイルすると下記のように数字が連番になるクラス名ができます。

CSS(コンパイル後)

  1. .test001 {
  2.  *****
  3. }
  4. .test002 {
  5.  *****
  6. }
  7. .test003 {
  8.  *****
  9. }
  10.  
  11. ~中略~
  12.  
  13. .test009 {
  14.  *****
  15. }

「from though」と「from to」の違い

@for構文の書き方には、実は「from though」と「from to」があります。

「from though」と「from to」の違いは次のとおりです。

thoughとtoの違い

概要
from thoughfromの値からthoughの値までループ処理をする
from tofromの値からtoの値の1つ前までループ処理をする

上の例を「from to」で記述するとコンパイル結果が変わり、次のようになります。

Sass

  1. @for $number from 1 to 9 {
  2.  .test00#{$number} {
  3.  ***** /*任意のプロパティ*/
  4. }

CSS(コンパイル後)

  1. .test001 {
  2.  *****
  3. }
  4. .test002 {
  5.  *****
  6. }
  7. .test003 {
  8.  *****
  9. }
  10.  
  11. ~中略~
  12.  
  13. .test008 {
  14.  *****
  15. }

変数の桁が変わる時の処理(@if構文)

上の例では変数が1~9までの一桁でしたが、これが「1~10」つまり一桁と二桁が混在する場合は記述方法が変わります。

例えば、これをこのまま上記のとおりに記述すると次のようにコンパイルされます。

Sass

  1. @for $number from 1 through 10 {
  2.  .test00#{$number} {
  3.  ***** /*任意のプロパティ*/
  4. }

CSS(コンパイル後)

  1. .test001 {
  2.  *****
  3. }
  4. .test002 {
  5.  *****
  6. }
  7. .test003 {
  8.  *****
  9. }
  10.  
  11. ~中略~
  12.  
  13. .test009 {
  14.  *****
  15. }
  16. .test0010 {
  17.  *****
  18. }

クラス名.test009の次は.test010とはならず.test0010と記述されてしまいます。

これはSassのクラス名が.test00#{$number}で設定しているので、数字の「00」の後に変数が代入されてしまうからです。

.test010というクラス名を作るには、クラス名を.test0#{$number}とする必要があり、「1~9」と「10~99」ではSass上のクラス名の記述を変える必要があります。

この場合、変数が「1~9」で記述するクラス名と「10~99」でクラス名を条件分岐して記述します。

条件分岐はSassの「@if」構文を使って記述します。

今回の例では次のようにSassを記述します。

Sass

  1. @for $number from 1 through 99 {
  2.  @if $number < 10 {
  3.   .test00#{$number} {
  4.    ***** /*任意のプロパティ*/
  5.   }
  6.  } @else {
  7.   .test0#{$number} {
  8.    *****
  9.    }
  10.  }
  11. }

@if構文で「変数$numberが10より小さい場合」と「それ以外(10以上)の場合」で条件分岐をします。

「10より小さい場合」のクラスは前回どおりですが、「10以上の場合」はクラス名を「.test0#{$number}」としています。

これをCSSにコンパイルすると以下のようになります。

CSS(コンパイル後)

  1. .test001 {
  2.  *****
  3. }
  4. .test002 {
  5.  *****
  6. }
  7. .test003 {
  8.  *****
  9. }
  10.  
  11. ~中略~
  12.  
  13. .test009 {
  14.  *****
  15. }
  16. .test010 {
  17.  *****
  18. }
  19.  
  20. ~中略~
  21.  
  22. .test098 {
  23.  *****
  24. }
  25. .test099 {
  26.  *****
  27. }

3つ以上に条件分岐したい時の処理

上の例では条件分岐が2つでしたが、3つ以上条件分岐をしたい場合は「@else if」を使います。

例えば今度は「0~100」までループ処理したい場合は「10より小さい場合」「10~99より小さい場合」「それ以外(100の場合)」という3パターンの条件分岐となり、下のようにそれぞれクラス名を調整します。

Sass

  1. @for $number from 1 through 99 {
  2.  @if $number < 10 {
  3.   .test00#{$number} {
  4.    ***** /*任意のプロパティ*/
  5.   }
  6.  } @else if $number < 100 {
  7.   .test0#{$number} {
  8.    *****
  9.   }
  10.  } @else {
  11.   .p-test#{$number} {
  12.    *****
  13.   }
  14.  }
  15. }

CSS(コンパイル後)

  1. .test001 {
  2.  *****
  3. }
  4. .test002 {
  5.  *****
  6. }
  7. .test003 {
  8.  *****
  9. }
  10.  
  11. ~中略~
  12.  
  13. .test009 {
  14.  *****
  15. }
  16. .test010 {
  17.  *****
  18. }
  19.  
  20. ~中略~
  21.  
  22. .test098 {
  23.  *****
  24. }
  25. .test099 {
  26.  *****
  27. }
  28. .test100 {
  29.  *****
  30. }

@from構文や@if構文を使う事で、Sassの記述が簡略化できますしファイルもスッキリして見えます。

一方で、体感としてコンパイルの処理時間が少し長くなったような気がしなくもないです(気のせいなら良いのですが)。

私はSassのコンパイルをDart Sassで行っていて、Sassを保存すると自動的にコンパイルされるように設定しています。

Dart Sassの場合(というかGulpで処理するの場合?)、コンパイルを繰り返すうちに段々とコンパイル時間が長くなるので、最近はこれをなんとか短くならないかなと思案しています。