【Sass/SCSS】チュートリアル-ミックスイン/関数/継承

皆さん、こんにちは。
本記事では、Sassのチュートリアルで学んだことを記事にまとめました。
今回は、Sassの機能であるミックスイン、関数、継承について解説します。一緒に理解を深めていきましょう。

※Sassの環境構築がまだの方はこちら。コンパイル方法も載せてます。
[【Sass】環境構築やってみた](https://qiita.com/yukimaruyama/items/d9a332900675cdfb3c4c)

※Sassの変数・ネストを学びたい方はこちら
[【Sass/SCSS】チュートリアル-変数とネスト](https://qiita.com/yukimaruyama/items/204e7cbb17f080ee166e)

## 実行環境
私の実行環境は以下の通りとなります。
実行環境が違う場合でも記述方式は変わりませんので安心してください。
ただし、私が採用しているのはSCSS構文になりますので、Sass構文の方は他の記事を参考にしてください。

| 項目 | Ver |
|:-:|:-:|
| Node.js | v20.16.0  |
| Gulp  | CLI v3.0.0 / Local v5.0.0 |
| Sass | v1.77.8 |
| dart2js ※DartSass| v3.4.4 |

## もくじ
[1．ミックスイン](#1ミックスイン)
[2．関数](#2関数)
[3．継承](#3継承)
[4．まとめ](#4まとめ)

## 1．ミックスイン
### 1.1.ミックスインとは
ミックスインとは、一度定義しておけば、何度でも呼び出せるスタイルの「部品」のようなものです。例えば、繰り返し使うスタイルをまとめて、必要な所で使いまわすことが可能です。

### 1.2.ミックスインの基本
**ミックスインの定義**
それではミックスインの使い方を説明します。
まず、``@mixin``を使ってミックスイン（部品）を定義します。
```scss:SCSS
@mixin rounded($radius) {
    border-radius: $radius;
}
```
上記について詳しく解説していきます。

**``@mixin rounded($radius)``**：``rounded``という名前のミックスインを定義。引数``$radius``は後でミックスインを呼び出す時に値を受け取るためのものです。

**``{ border-radius: $radius; }``**：波括弧( {} )の中にCSSプロパティを記述します。
``border-radius``の値として、引数``$radius``を使います。

**ミックスイン呼び出し**
ミックスインは定義しただけでは使えません。実際に使うには、``@include``を使って、スタイルを適用する要素に対して呼び出します。
```scss:SCSS
@mixin rounded($radius) {
    border-radius: $radius;
}

button {
    @include rounded(10px);
}
```
**``button { @include rounded(10px); }``**：``@include``を使ってミックスイン``rounded``を呼び出します。引数に``border-radius``の値となる10pxを指定。
このようにすることで、このボタンの``border-radius``プロパティに10pxが適用され、角が10pxの半径で丸められます。

### 1.3.ミックスインの応用
基本的なミックスインの使い方が理解できたでしょうか。
次に少し応用的なミックスインを使ってみます。
以下のSCSSコードは、ボタンのスタイルを定義し、色やサイズを柔軟に設定できるようにします。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="xxojBWZ" data-pen-title="Untitled" data-user="iwdulmiq-the-builder" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/iwdulmiq-the-builder/pen/xxojBWZ">
  Untitled</a> by 丸山悠希 (<a href="https://codepen.io/iwdulmiq-the-builder">@iwdulmiq-the-builder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

※1 "Result"ボタンを押すとプレビューが表示されます。
※2 SCSS欄の下部、"View Compiled"を押すとCSSにコンパイルされたコードを見ることができます。

それでは順番に解説していきます。
**``@mixin button-style($color, $background-color, $padding: 10px)``**：``button-style``というミックスインを定義し、引数``$color``、``$background-color``を定義しています。引数``$padding``には、デフォルトとして10pxを設定しています。

**波括弧( {} )内**：波括弧( {} )内は、先ほどと同じようにCSSプロパティを記述しています。CSSプロパティの説明は割愛してポイントだけ説明します。
``color: $color;``：``color``プロパティの値として、第一引数``$color``を指定。
``background-color: $background-color;``：``background-color``プロパティの値として第二引数``$background-color``を指定。
``padding: $padding;``：``padding``プロパティの値として、第三引数``$padding``を指定。※デフォルト値は10px

**``.btn--large { @include button-style(#fff, #007bff, 15px); }``**：クラス``button-style``に対して、ミックスインを呼び出します。呼び出す時は``@include``を使います。
丸括弧()内で第一引数～第三引数にCSSプロパティの値を指定しています。

**``.btn--small { @include button-style(#fff, #28a745, 5px); }``**：こちらもクラス``.btn--small``に対して、ミックスインを呼び出し、CSSプロパティの値を指定しています。

**まとめ**
このようにミックインは同じスタイルを書く手間が省き、定義したCSSプロパティを使ってスタイルを適用することができます。さらに、引数を使うことで要素によって色やサイズを柔軟に変更することが可能になります。また、スタイルの変更があった時にミックスインだけを変更すれば全体に反映できるため、保守がしやすくなります。

## 2．関数
### 2.1.SCSSの関数とは
SCSSの関数は、プログラミングでいう関数と同じように、何らかの計算や操作を行って、処理を返すことができます。もちろんオリジナルの関数を作ることもできます。また、SCSSにはいくつかの組み込み関数も用意されています。

### 2.2.組み込み関数
SCSSの組み込み関数を一部を紹介します。

**・lighten()**
フォントカラーや背景色を明るくします。

**・darken()**
フォントカラーや背景色を暗くします。

実は、**ミックスインの応用**で関数``darken()``を使用して、ホバー時に背景色が暗くなるスタイルを適用していました。簡単ではありますが、使い方を説明しますので興味のある方は試してみてください。

**基本構文**
``CSSプロパティ: lighten(カラーコード, パーセント値)``
``CSSプロパティ: darken(カラーコード, パーセント値)``

CSSプロパティには、``color``や``background-color``を指定し、関数の第一引数にカラーコード、第二引数に何％明るくしたいか、暗くしたいかを指定することで、色の明度を変更することができます。

### 2.3.オリジナル関数

プログラミングでいう関数と同じように、関数を定義することができます。頻繁に使う処理は、関数にまとめておくと開発の効率化に繋がります。

**関数の定義と呼び出し**
SCSSで関数を定義するには``@function``を使い、処理結果を返す時には``@return``を使います。

```:SCSS
@function 関数名 (第一引数, 第二引数，…) {
  @return 処理
} 
```

**オリジナル関数の用途**
関数を定義できることは分かりましたが、どのような時に関数を使うのかイメージが湧かないですよね。調べた所、主な用途として、サイズの計算などにオリジナル関数が使われていることが分かりました。
下記に一例を紹介します。

**pxをremに変換**
以下の``to-rem()``関数は、pxをremに変換する処理を行います。こちらの関数を呼び出すことで、自身で換算する手間が省けるので便利ですよね。

```scss:SCSS
@use 'sass:math';  //mathモジュールのインポート

// 基本のルートフォントサイズを16pxに設定
$base-font-size: 16px;

// pxをremに変換する関数
@function to-rem($px) {
    // @return ($px / $base-font-size) * 1rem;
    @return math.div($px, $base-font-size) * 1rem;
}

body {
    font-size: to-rem(16px); //1remに変換
}

h1 {
    font-size: to-rem(32px); //2remに変換
    margin-bottom: to-rem(24px); //1.5remに変換
}

p {
    padding: to-rem(10px); //0.625remに変換
}
```
上記コードのポイントだけ解説します。
``@use 'sass:math';``；``@use``は、モジュールや他のSassファイルをインポートする為に使います。``math``は、Sassの標準ライブラリの一部で、数学的な計算を行う関数です。remに換算する計算は単純なのですが、なぜこの関数を使うのか、それには以下の理由があります。

**・除算処理の仕様変更**
Sass Ver1.33.0以降から除算に関する仕様が変更されたとのことです。[※Sass公式参照](https://sass-lang.com/documentation/breaking-changes/slash-div/)
( / )演算子を使った除算処理はできますが、コンパイル時に警告が出ます。そこで( / )演算子の代わりに追加されたのが``math.div``になります。``math.div``は、( / )演算子と同じ除算の処理をする関数になります。使い方は、``math.div(割られる数, 割る数)``とすることで簡単に処理を行えます。

**補足**
関数内で``px``と``rem``という異なる単位を持つ値を乗算しています。乗算結果は``rem``になりますが、これは相対単位である``rem``が優先される仕様になっているためです。


## 3．継承
### 3.1.継承とは
SCSSの**継承**とは、すでに定義したスタイルを継承することで、継承先に同じスタイルを適用することができます。これによりコードの重複を減らすことができます。

### 3.2．継承の使い方
継承する時は、``@extend``を使います。継承元のスタイルがそのまま継承されます。
それでは、簡単な継承をやってみます。

<p class="codepen" data-height="300" data-default-tab="html" data-slug-hash="wvLXNpM" data-pen-title="Untitled" data-user="iwdulmiq-the-builder" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/iwdulmiq-the-builder/pen/wvLXNpM">
  Untitled</a> by 丸山悠希 (<a href="https://codepen.io/iwdulmiq-the-builder">@iwdulmiq-the-builder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

上記SCSSコードの解説をします。
``.btn--main {
    @extend .btn;
    font-weight: bold;
}``：``@extend``を使ってクラス``.btn``からスタイルを継承します。これにより、継承先のクラス``.btn--main``に継承元のスタイルが引き継がれます。さらに新たなCSSプロパティ(太字)を加えることで、追加のスタイルを適用することができます。

### 3.3. 継承とミックスイン
お気づきの方もいるかもしれませんが、再利用という点で継承とミックスインは少し似ています。どちらを使うか悩みますよね。個人的には、複数の要素に同じスタイルを適用する場合は、継承を使うのが効率的だと思いました。一方でミックスインは、引数を使うことで柔軟にスタイルを適用することができます。シーンに合わせて使い分けましょう。

## 4.まとめ
本記事では、ミックスイン、関数、継承の基本的な使い方を説明しました。
これらは、Sassにおいて重要な機能です。効率的にSassコードを記述するには不可欠な機能となりますので、しっかりと基本を押さえておきましょう。
長々とありがとうございました。