Sass の個人的まとめ

## 概要
Sassについての使い方などの個人的な学習記録。

## Sassとは

Syntactically Awesome StyleSheet.
CSSの機能拡張。CSSの記述量を減らし、再利用を可能にする。
生産性の向上、保守性の向上などのメリットがある。  

記述方法が2つある。

**SCSS**
拡張子はscss。通常のCSSの記述スタイルに近いため、慣れやすいし、導入しやすい。
SASSよりも広く使われており、情報も得やすい。

```scss
ul {
    margin: 0;
    padding: 0;

    li {
        margin: 0;
    }
}
```


**SASS**
拡張子はsass。比較相対的に、記述量は少ない。
インデントでネストを表現するので、ブランケット {} の分記述を省略できる。 
また、末尾のセミコロンも不要。CSSとは多少記述スタイルが違うので、ちょっとだけ学習コストがある。

```sass
ul
    margin: 0
    padding: 0

    li
        margin: 0
```

**所感**
cssではなくsassを使うのは既に一般化しているし、基本的には、保守性や開発効率の観点からも
ある程度以上の規模のフロント開発で使わない理由はない。    

SASSとSCSSどちらの書き方で行くかは、プロジェクトの文化によって選択する。
記述量を最大限減らす文化ならSASSを、誰が見ても分かりやすい記述方法を取る文化ならSCSSを。  


**導入選択は、単体ではなくHTMLのマークアップ方法とセットで考えた方が良い。**
というのも、SASSを導入する場合は、CSS部分だけ記述量を減らしても恩恵は最大限得難いので、
HTML部分もPugなど同様の思想の表現で記述量を省略できるツールを入れて統一したい。

とはいえ、sassとscsssは機能同等で自動変換ツールもあるので、決めの問題。
**迷ったらSCSSで良いと思う。**

以下ではSCSSを扱いその基本的な機能についてまとめる。

## SCSSの各種機能

- ネスト表現
- 変数定義
- mixin
- 関数
- import

### ネスト表現
ブランケットで囲むことで、ネスト構造を表現できる。&で連結を表現して、擬似クラス(:active)なども使える。
単純に同じセレクタをなんども書かない分、コーディングで楽できる。クラス名の変更も変更箇所が少なく楽々。
それ以上に、CSS内の各宣言に、 **規則性/まとまりをつくって構造化できるのが大きい** と思う。
俯瞰把握をしやすくし、宣言のとっ散らかりを防ぐことができる。
副次的に、ネストが深くなった時に記述/設計を見直す機会も与えてくれる。

```scss

/* --cssでの記法-- */
.news {}
.news li {}
.news li:hover {}

/* --scssでの記法-- */
.news {
 li {
   &:hover{}
 }
}
```

### 変数定義
'$'　プレフィックスから始まる変数名を定義できる。
**定義位置とスコープに注意する必要がある。**
定義位置: 使用箇所より先に定義されていないといけない同一CSSなら上の方。
スコープ: ネスト内で定義された変数は、そのネスト内部でのみ有効。

**使い方**
グローバル変数的/定数的な扱いのものは、variablesみたいなプロジェクト設定変数を固めた専用cssを用意して、そこに集めて管理するなど。
ネスト内でのみ有効な変数を定義したい場合は最初の方に固めて記述しておく。

```scss
$primary-color: #ff3300;

h1 {
 color: $primary-color;
}
```
### mixin 
複数のCSS宣言を名前をつくってくくり、再利用できるようにしたもの。
@mixinで定義し、@includeで利用する。
(cssにコンパイルされた際には、中身がごそっとコピーされるので、やみくもに乱用すると
コンパイル後のスタイルシートサイズがでかくなるので、ちょっとだけ意識。
とはいえ、最初は気にせずに使って慣れるのが大事)

```scss

/** mixin 定義 **/
@mixin default-card {
  width: 300px;
  padding: 20px;
  background-color: #fff
}

/** mixin 利用 **/
.profile-card {
 @inlcude default-card;
}

```

**引数**
より実践的には、変更が加わりそうなホットポイントを割り出し、
引数を使用することで、再利用生を高めることができる。
**引数を利用する際には引数名(ラベル)とデフォルト値をつけておけば便利。**

```scss

/** カードサイズ(width)は固定でpaddingと色味は調整ポイントと想定 */
@mixin default-card($padding: 20px, $bgcolor: white) {
  width: 300px;
  padding: $padding;
  background-color: $bgcolor;
}

.profile-card {
 /** デフォルト値で使用する */
 @inlcude default-card();
}

/** 引数名・デフォルト値を設定することで順番を気にせず必要なものだけ狙って調整可能 */
.news-card {
 @inlcude default-card($bgcolor: black);
 /** @inlcude default-card($bgcolor: black, $padding: 15px); **/
}

```

ちょっと似た機能に、@extend というものがあるが使いどころが難しいので、最初のうちはmixinを利用していく。

補足: extendはセレクタの継承関係を作る。
cssにコンパイルされた後はセレクタをグルーピングして、基底要素を宣言する。
だから不用意に使うと、コンパイル後のcssに大量にグルーピングされたセレクタを生み出してしまい、デバッグが難しくなったりする。
プログラミングにおいて、継承より委譲じゃないけど、しっかり設計しないと継承関係(is-a)が使い難いような感じ。
使う場合は、親子の関係性が意味合い的にも現実的にも、今後普遍/不変の確信をもって使用する。

**所感**
mixinは少なくても機能面で言えば、sassを利用する最大の理由になるものだし、使いこなせるようになりたい。
基本的には、再利用の気配を感じたら、mixinを定義する。
ホットポイントが読めない場合はデフォルト値とラベルがついた引数に逃しておいて定義するのが良いと思われる。
汎用的なmixin定義は自分の資産にもなるので蓄積していきたい。

## 関数

@functionで独自関数を定義して利用できる。
**主に値のみ(場合によりセレクタ)を返す用途で、関数を定義できる。**
同じようなプロパティ値の計算指定を毎回書いてるなと思ったら関数に切り出せないかを検討する。
もともと組み込まれた関数 = ネイティブ関数もある。(明るい色味を返却するlighten関数など)

ネイティブ関数については、下記のbuildin-methodを参照
> https://sass-lang.com/documentation/modules

以下に具体例を示す。

```scss
/** 定義
@function 自作関数名($引数){
    @return 戻り値;
}**/

// pxからrem単位への変換を行う
//
// toRem(8, 16) -> 0.5rem
//
@function toRem($fontSize, $baseFontSize : 16) {
    @return unquote(($fontSize / $baseFontSize) + "rem");
}

.news {
 p {
  // 関数呼び出し 0.75rem が設定される
  font-size: toRem(12);
 } 
}
```

**所感**
関数に、ifなどの制御分構造などを組み合わせれば、柔軟性も高く夢は広がるがやりすぎない程度に。
基本的には、独自関数を定義する前にネイティブ関数を使いこなせるようになるべきだと思う。
普遍的に必要なものは、そこに入っていると思うので。
守破離じゃないが、オレオレ定義する前に、まずは用意されたものを使い倒すことを心がけたい。

## import

scssファイルを分割して管理する。読み込み側ではimportで読み込める。
importの記述方法は２種類ある。　　　

- プレフィックス'_'と拡張子を用いたもの
- 拡張子とプレフィックスを省略したもの

以下に例を示す。

```scss

/** プレフィックス拡張子ありversion */
@import "_colors.scss";

/** 拡張子省略バージョン */
@import "colors";

``` 

**所感**
基本的には省略バージョンの方を使うでよさそう。(万が一拡張子が変わった場合なども考えて)
どのような単位でscssファイルを分割して管理していくかは、いろんな有識者がそれぞれで
見識/戦略をまとめている。単独での深いテーマになりそうなので、また別の記事としてまとめる。