Sassの@eachを使い、設定した値があるぶんだけ順番に複数classを作成する方法[Sass, Scss]

Sassの@eachを使い、設定した値があるぶんだけ順番に複数classを作成する方法

前回の記事に続いて、今回もSassの記事になります。

前回はSassのfor文を使って、指定した一定のパターンを持つclassを複数作成する、ということについて書きました。

今回は、Sassの @each を使って、複数の値を順番に適用したclassを作成する方法について書いていきたいと思います。

用意したリストの中身を、順番に割り当てることができるSassの@each

Sassの @each で何ができるかというと、次の様なことになります。

$positionValues: static, relative, absolute, sticky;

@each $value in $positionValues {
  .is-#{$value} {
    position: $value;
  }
}

上記のSass(記法はSCSS記法)の例では、
1行目で $positionValues として、4つの値を定義しています。
これを、
3行目にあるSassの@eachを使ってコンパイルさせることで、次の様な4つのclassを書き出すことができます。

.is-static {
  position: static;
}

.is-relative {
  position: relative;
}

.is-absolute {
  position: absolute;
}

.is-sticky {
  position: sticky;
}

↑ $positionValues に定義した4つの値が順番に展開されて、4つのclassが出来ていますね。
例えばWebサイトで、ヘルパークラス(補助的に付与するクラス)を量産する場合などに役立ちそうです。

…ただ、この例だけだといまいちで、
「手動で書いた方が効率いいのでは…?」と思う方もいるかもしれません。
(…書いている私自身、そう思いました。)

そこでご紹介したいのが、次のセクションの内容です。実はこのSassの@each文、
「複数の値を、複数の項目に」それぞれ割り当ててコンパイルさせることもできたりします。

次のセクションでは、上記の書き方を応用して
「異なる複数の値」を持たせたclassを、一発で書き出す方法について書いていきます。

応用例。5つの異なる値を持ったclassを、一発で書き出す方法

たとえばWebサイトを制作していて、サイズが決定した
小、中、大の3つのボックスのcssを、効率よく書き出したい場合。

[Scss(Sass)側]

$boxValues: (
  "mini" 1rem 100% 16px auto,
  "middle" 2rem 100% 16px auto,
  "large" 3rem 100% 16px auto
);

@each $name, $height, $width, $padding, $margin in $boxValues {
  .box-#{$name} {
    height: $height;
    margin: 0 $margin;
    padding: 0 $padding;
    width: $width;
  }
}

↑これをコンパイルすると、なんと次の様に
見事にそれぞれの値を割り当てた3つのボックス用のcssができてしまう、というわけです。

[コンパイル後のcss]

.box-mini {
  height: 1rem;
  margin: 0 auto;
  padding: 0 16px;
  width: 100%;
}

.box-middle {
  height: 2rem;
  margin: 0 auto;
  padding: 0 16px;
  width: 100%;
}

.box-large {
  height: 3rem;
  margin: 0 auto;
  padding: 0 16px;
  width: 100%;
}

値を定義する → @each を使って順番に割り当てる

上のセクションで書いたことのもう少し詳しい説明です。

Sass側の $boxValues には、

"mini" 1rem 100% 16px auto,

↑このように5つの値をもった項目を、

"mini" 1rem 100% 16px auto,
"middle" 2rem 100% 16px auto,
"large" 3rem 100% 16px auto

↑小、中、大サイズのボックス用に、3つ定義しています。

これを、Sassの @each を使って、順番に割り当てることで、
3種類のボックス用cssが見事にコンパイルできてしまう、ということです。

@each $name, $height, $width, $padding, $margin in $boxValues {
  .box-#{$name} {
    height: $height;
    margin: 0 $margin;
    padding: 0 $padding;
    width: $width;
  }
}

“mini” 1rem 100% 16px auto
↑このように定義してある5つの値が、

$name, $height, $width, $padding, $margin
↑左から順にこれら5つの変数にそれぞれ対応して、コンパイルされると
小、中、大サイズの3つのボックス用classとして展開される、というわけです。

[コンパイル後のcss]

.box-mini {
  height: 1rem;
  margin: 0 auto;
  padding: 0 16px;
  width: 100%;
}

.box-middle {
  height: 2rem;
  margin: 0 auto;
  padding: 0 16px;
  width: 100%;
}

.box-large {
  height: 3rem;
  margin: 0 auto;
  padding: 0 16px;
  width: 100%;
}

これを使いこなすと、かなり便利に
Sass(SCSS)を書いていける気がしますね。

・値を定義する箇所

・展開される式

をそれぞれ一箇所で定義しておけるので、メンテナンス性の面でも効率が良さそうですね。

公式サイトの解説ページ

Sass公式サイトの、@eachについての解説ページは以下になります。
Sass: @each | sass-lang.com
↑@each で使うことができる各種の書き方が、サンプルコード付きで載っています。
アイコンフォント用のclassを複数作成することを想定した例などもあり、参考になります。

この記事のまとめ

今回は、Sass の each文を使い、
異なる複数の値を持たせたclassを、一発で書き出す方法について書きました。

cssプリプロセッサの定番として、すっかり定着している感のあるSass。
前回ご紹介した@forや、今回の@eachを適切に使うことで、
より効率の良いWeb制作ができるかと思います。

また、@forや@eachを使おう、と思うと
どう効率よくcssを書くか?」という発想に行き着きます。

すると、自然と「cssを設計する」という概念にも行き着くと思います。

なんとなく漠然とcssを書いている」状態と
cssを設計して書いている」状態、どちらが良いかは明白ですよね。

当サイトでは、今後もWebデザイン、Web制作に関する記事を引き続き書いていきます。
Sassに関する記事も、何かおもしろいサンプルを思いついたら、また書いていきたいと思っています。