murketでのSassの変数・@mixinのご紹介

この記事は[レコチョク Advent Calendar 2021](https://qiita.com/advent-calendar/2021/recochoku)の2日目の記事となります。

https://qiita.com/advent-calendar/2021/recochoku

## 前書き

はじめまして！
好きなものはみかんゼリーとアイドル、嫌いなものはマンゴーゼリーと掃除機の音、おおくぼです。

普段はレコチョクで各サービスのウェブ画面を作るお仕事をしています。
直近は10月に始まったmurket(ミューケット)を作っています。
【隙あらば宣伝】murketについてはこちら → https://recochoku.jp/corporate/murket/

今回はそのmurket開発での個人的こだわりポイントとして、Sassの変数や@&#xFFF0;mixinについてお話できればと思います。

簡単にはなりますが変数や@&#xFFF0;mixinの定義の参考になれば幸いです。


## 前提

前書きにも一部出てきましたが、murketではCSSを書く際にSass(SCSS記法)を使用しています。
Sassの公式サイト → https://sass-lang.com/

SASS記法ではネストを使用し以下のように書きます。

```sass
.selector
	color: #ff0000
```
それに対しSCSS記法ではよりCSSに寄せた書き方で、 `{` や `}` 、 `;` を使用し以下のように書きます。

```scss
.selector {
	color: #ff0000;
}
```

今回の記事では後者の書き方になりますのでご承知おきください。

## 本題 - 変数編
### Sassの変数って？

Sassでは↓のように値を変数として持つことができ

```scss
// 変数の定義
$red: #ff0000;

// 変数の使用
.selector {
	color: $red;
}
```
CSSにすると↓のようになる

```css
.selector {
	color: #ff0000;
}
```
というものです。
サイト全体で統一したい値は変数にしてあげると変更にも柔軟に対応できて楽です。
公式サイトの説明はこちら → https://sass-lang.com/documentation/variables

### murketでは何を変数にしてたの？

大きく以下4つを変数化していました。

- 余白
- フォントサイズ
- レスポンシブデザイン用のブレイクポイント
- 色

どれもmurket内で共通使用するとサイトの統一感も取れていい感じになります。

### 具体的な変数の定義方法は？

余白やフォントサイズ、ブレイクポイントは変数にそのまま値を定義して完了。
何を意図する値か分かるように余白には `margin-`、フォントサイズには `font-` 、ブレイクポイント(画面幅)には `width-` とプレフィックスを付けています。
その上で、余白とフォントサイズに関しては数種類あるのでそれぞれ `-small`  `-medium` `-large` みたいな風に名付けてました。

```scss
// 余白
$margin-large: 24px;
$margin-medium: 16px;
$margin-small: 8px;

// フォントサイズ
$font-large: 18px;
$font-medium: 16px;
$font-small: 14px;

// PCの最小画面幅(ここからPCビュー)
$width-for-pc: 960px;
```

残った色の定義方法について。
murket内のSass管理方法で結構悩んだのがこれでした。

というのも、murketでは多種多様なグレーが使われています。
実際全部書き出すとこんな感じ。

```
#222222 // 基本的な文字色
#2c2c2c // 特定の部分の文字色
#505050 // 基本的なアイコン色
#707070 // 特定の部分のボーダー色
#888888 // 明るめのアイコン色
#a0a0a0 // 特定の部分のアイコン色
#aaaaaa // 特定の部分のボーダー色
#d0d0d0 // 基本的なdisabled色
#e0e0e0 // ヘッダーのアイコン色
#f0f0f0 // 基本的なボーダー色
#f4f4f4 // 特定のボタン背景色
```
つまり、余白と同じテンションで命名すると

```scss
$color-black: #222222; // ←一旦この中で一番黒いからblack
$color-light-black: #2c2c2c; // ←blackよりは白いからlightとかにしとくかあ...
$color-dark-black-medium-gray: #505050; // ←black-medium-grayよりは黒いから、頭にdarkとか付けとく？
$color-black-medium-gray: #707070; // ←blackとmediumの間だからmudium-black？
$color-dark-medium-gray: #888888; // ←ここはmediumより黒いからdark-mediumでしょ！
$color-medium-gray: #a0a0a0; // ←真ん中だからmediumとか付けとく？
$color-light-medium-gray: #aaaaaa; // ←ここはmediumより白いからlight-mediumでしょ！
$color-dark-white-medium-gray: #d0d0d0; // ←white-medium-grayよりは黒いから、頭にdarkとか付けとく？
$color-white-medium-gray: #e0e0e0; // ←whiteとmediumの間だからmedium-white？
$color-dark-white: #f0f0f0; // ←whiteよりは黒いからdarkとかにしとくかあ...
$color-white: #f4f4f4; // ←一旦この中で一番白いからwhite
```
みたいな感じになってしまいます。

結構命名自体にも悩んでしまいますし、実際に変数を使うときに「あれ、light-medium-grayとdark-white-medium-grayってどっちの方が白いんだっけ??」にかなりの確率で陥るわけです。

あと単純に変数名を覚えられない。

という訳でmurketでは色をHSVに変換したV(明度)の値を用いて `$color-gray-[Vの値]` で命名しています。
さっきの色たちはこんな感じで命名することができます。

```scss
$color-gray-13: #222222; // ←HSVでは(0, 0, 13)の色なので13を用いて $color-gray-13
$color-gray-17: #2c2c2c;
$color-gray-31: #505050;
$color-gray-44: #707070;
$color-gray-53: #888888;
$color-gray-63: #a0a0a0;
$color-gray-67: #aaaaaa;
$color-gray-82: #d0d0d0;
$color-gray-88: #e0e0e0;
$color-gray-94: #f0f0f0;
$color-gray-96: #f4f4f4;
```
これで新しく色が増えても命名に困らず、どっちが白いかも悩まず、変数名も最後の番号なんだっけ?くらいの思い出しでOKです。

ちなみに、murketではより分かりやすくするため以下のように用途に合わせた変数を再定義しているものもあります。

```scss
$border-main: $color-gray-94;
$font-main: $color-gray-13;
$icon-main: $color-gray-31;
$background-disabled: $color-gray-82;
$background-btn: $color-gray-96;
```

## 本題 - @&#xFFF0;mixin編
### @&#xFFF0;mixin(ミックスイン)って？

先程の変数は値を入れるものでしたが@&#xFFF0;mixinはスタイルを使い回すために役に立つものです。
Sassでは↓のように頭に `@mixin` を付けて定義、頭に `@include` を付けて使用することができ

```scss
// @mixinの定義
@mixin disable-text {
	color: $color-gray-82;
	font-size: $font-small;
	line-height: 1.5;
}

// @mixinの使用
.selector {
	@include disable-text;
	background: red;
}
```
CSSにすると↓のようになる

```css
.selector {
	color: #d0d0d0;
	font-size: 14px;
	line-height: 1.5;
	background: red;
}
```
というものです。
@&#xFFF0;mixinは引数を持つことができるので↓のようにすることもできます。

```scss
// @mixinの定義
@mixin disable-text($line-height: 1) { // 引数があったらそれを$line-heightとして使用、デフォルト値は1
	color: $color-gray-82;
	font-size: $font-small;
	line-height: $line-height;
}

// @mixinの使用
.selector {
	@include disable-text(1.5);
	background: red;
}
```

CSSにした結果は先程と同じなので割愛。

変数同様にサイトで統一したいものだったりとかこうしたい時は大体書くこと決まってるよねということがあったりする場合に便利です。
公式サイトの説明はこちら → https://sass-lang.com/documentation/at-rules/mixin

### murketでは何を@&#xFFF0;mixinにしてたの？

大きく以下4つを@&#xFFF0;mixin化していました。

- テキスト
- SVGで作られるアイコンの設定
- z-index
- position: absoluteでの中央揃え

全部詳細を書くと長くなってしまうので、今回は「サイトで統一したいもの」の例としてz-indexについて、「こうしたい時は大体書くこと決まってるよね」の例としてabsoluteについて詳細を書きます。

### 具体的な@&#xFFF0;mixinの定義方法は？

まずはz-indexについて。
murketでは何が何の上にあるのかが分からなくならないようにz-indexの値を@&#xFFF0;mixinで管理していました。

```scss
// @mixinの定義
@mixin z-index($target) {
    @if $target == 'modal' {
        z-index: 30;
    }
    @else if $target == 'overlay' {
        z-index: 25;
    }
    @else if $target == 'header' {
        z-index: 20;
    }
    @else if $target == 'float-element' {
        z-index: 10;
    }
}

// @mixinの使用
.modal {
	@include z-index('modal');
}

.header {
	@include z-index('header');
}
```
これにより「あれ、モーダルを出したのにヘッダーの後ろに回っちゃったよ！？」というバグの発生が少なく&バグの発見が早くなりましたし、各スタイル宣言場所で確認しなきゃいけなかったz-indexの値も@&#xFFF0;mixinでパッと見て分かるようになりました。

最後にabsoluteについて。
positionをabsoluteにして中央に設置したい時などは書くことが大体決まっているので@&#xFFF0;mixinにしてしまいます。

```scss
// @mixinの定義
@mixin center-alignment {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

// @mixinの使用
.parent {
	position: relative;
}

.child {
	@include center-alignment;
}
```
これにより決まりきったものを書く手間が若干省け、書き間違いなどのリスクも減少しました。

## 後書き
簡単ですがmurketで使っているSassの変数や@&#xFFF0;mixinを一部紹介しました。
個人的には開発着手時に何をどのように定義すればやりやすいかな??と悩むことが多かったので、一案としてお役に立てればなと思います！


明日の[レコチョク Advent Calendar 2021](https://qiita.com/advent-calendar/2021/recochoku)は3日目「えを描こう」です。お楽しみに！

---

この記事は[レコチョクのエンジニアブログの記事](https://techblog.recochoku.jp/7879)を転載したものとなります。

https://techblog.recochoku.jp/7879