【Sass】駆け出しエンジニアがCSS設計を理解するまで vol.2

こんちは！

30代半ばの駆け出しエンジニアheyheyです！

予告した通り、今日はCSS設計に影響を与えているSassについて勉強していきましょう。([前回の記事](https://qiita.com/heyhey1028/items/962a712826c25faf68e2)ではCSS設計思想を見ていきました)

##Sassとは

Syntactically Awesome StyleSheetの略。大元の概念としてSassが有り、その２つの記法としてSASS(.sass)とSCSS(.scss)があります。

SassはCSSを拡張したRuby製のCSSメタ言語です。メタ言語は「ある言語について何らかの記述をするための言語」という注釈ですが正直何のこっちゃよくわかりません。

通常のCSSとは違い、変数やmixinと呼ばれる関数を使って書く事が出来、CSSをプログラムの様に書く事でコーディング効率やソースコードの保守性が高まります。

これにより複数のSassファイルをimportし、コンパイルする事で１つのCSSにまとめる事も可能です。関数や変数の処理を行う為に「プリプロセッサ」と呼ばれたりもします。

2006年にSASS記法として誕生し、その後、よりCSSとの互換性が高いSCSS記法が生まれました。


##書き方の違い

まず通常のCSSとの書き方の違いを見てみましょう

```css:CSS
    div {
        margin: 0 auto;
    }
     
    div p {
        padding: 20px;
    }
```

```sass:SASS記法
    div
      margin: 0 auto
      p
        padding: 20px
```

記述が非常に簡潔で、スタイルの後ろのセミコロンも省略されています。依存関係はインデントで表現されています。

```scss:SCSS記法
    div{
      margin: 0 auto;
      p{
        padding: 20px;
      }
    }
```

セミコロンも括弧{}も使い、通常のCSSとかなり酷似していますね。SCSS記法では括弧{}を使い入れ子構造にする事でCSSの依存関係を示します。


##Sassで出来る事

書き方の違いで紹介した入れ子構造を表現する以外にも特徴的な機能がSassでは使えます。いくつか見ていきましょう。以下サンプルのコードはSCSS記法で記述していきたいと思います。

1. ネスト(入れ子)出来る
2. 親参照セレクタ&が使える
3. 変数が使える
4. extend(継承)が使える
5. mixin(関数)が使える
6. import出来る

###1.ネスト(入れ子)出来る
こちらは書き方の違いでもお見せした通り、入れ子構造にする事でCSSスタイルの依存関係を表現する事が出来ます。


###2.親参照セレクタ&が使える
& を記述する事で、CSSへのコンパイル時に親のセレクタを自動で付与してくれます。

```css:SCSS
    a{
      text-decoration: none;
      &:hover {
        color: red;
      }
      &::before {
        content: "LINK";
      }
    }
```

```css:コンパイル後(CSS)
    a {
      text-decoration: none;
    }
    a:hover {
      color: red;
    }
    a::before {
      content: "LINK";
    }
```

###3.変数が使える
「$」マークから始まる変数名を定義する事で様々な場面で使い回す事が出来ます。例えばサイトのメインカラーやサブカラーを一気に変更したい時に変数を書き換える事で一気に変更する事も可能です。

```scss:SCSS

    $main-color:#222;←変数を定義
    $sub-color:#ccc;
    #hoge{
      color:$main-color;←変数を代入
      a{
        color:$sub-color;
      }
    }
```

```css:コンパイル後(CSS)

    #hoge{
      color:#222;←変数の値が代入されている
    }
    #hoge a{
      color:#ccc;
    }
```

###4.extend(継承)が使える
@extendを用いる事でセレクタにつけたスタイルを継承し再利用する事が出来ます。呼び出し方は「@extend セレクタ名(idは頭に#、classは頭に.)」

```scss:SCSS

    .button {
        display: inline-block;
        border: 1px solid red;
        padding:20px;
        border-radius: 30px;
    }
    
    .button-red {
        @extend .button;
    
        background: red;
    }
```

```css:コンパイル後(CSS)

    .button {
      display: inline-block;
      border: 1px solid red;
      padding:20px;
      border-radius: 30px;
    }
    
    .button-red {
      display: inline-block;
      border: 1px solid red;
      padding:20px;
      border-radius: 30px;
    
      background: red;
    }
```

###5.mixin(関数)が使える
extend(継承)とも少し似ていますがこちらもコードの再利用の為の機能。extendと異なる点は、名前を付けて管理が出来る事、引数が使える事です。

定義する時は「@mixin mixin名」、呼び出す時は「@include mixin名」となります。

**引数無し**

```scss:SCSS

    @mixin button{
       display: inline-block;
       padding: 10px;
       border:1px solid red;
       background: #fff;
    }
    
    .button-red {
       @include button;
       background: red;
    }
```

```css:コンパイル後(CSS)

    @mixin button{
       display: inline-block;
       padding: 10px;
       border:1px solid red;
       background: #fff;
    }
    
    .button-red {
       display: inline-block;
       padding: 10px;
       border:1px solid red;
       background: #fff;
    
       background: red;
    }
```

**引数有り**
引数を使用したい場合は、変更したい値に変数を付けて、mixin名の後ろに($変数名)。　変数名の後ろをコロンで繋いで初期値を設定する事も出来ます。

```scss:SCSS

    @mixin button($color:#000) ←引数を受け取れるようにし、初期値も設定
    {
       margin: 10px;
       padding: 10px;
       font-size: 10px;
       background: $color;←引数がこちらに代入されます
    }
    
    .button-blue {
       @include button;
       background: blue;
    }
```

```css:コンパイル後(CSS)

    @mixin button($color:#000) 
    {
       margin: 10px;
       padding: 10px;
       font-size: 10px;
       background: $color;
    }
    
    .button-blue {
       margin: 10px;
       padding: 10px;
       font-size: 10px;
       background: #000;←引数が代入されました
    
       background: blue;
    }
```

引数を受け取る場合の注意としては初期値を設定せずに、引数を何も渡さないとエラーなります。

```scss:SCSS
    @mixin button($color) {
       background: $color;
    }
```

`@include button;`→エラー
`@include button(#fff);`→$colorに「#fff」が入る

###6.importが使える
変数やmixinなど機能ごとに別ファイルにしても@importを行う事で、1つのファイルにまとめてインポートする事が出来ます。

インポート先のファイルをコンパイルすれば全てのimportしたスタイルも含めてスタイルが適用されるという寸法です。

```scss:scss
    @import "./settings.scss"
    @import "./mixins.scss"
```

###SassとSMACSS, FLOCSS

前回こちらで「CSS設計思想のSMACSS、FLOCSSはSassを使う事を前提としている」とお伝えしました。

SMACSSとFLOCSSの特徴は以下の通りでした。
**SMACSS**
 - Base, Layout, Module, State, Themeの階層構造
 - クラスに接頭辞を付ける

**FLOCSS**
- Foundation, Layer, ObjectとObject内にComponent, Project, Utilityの階層構造
- クラスに接頭辞を付ける
- 命名規則MindBEMdingに則る

SMACSS、FLOCSSは上記の通り、役割ごとにレイヤー分けをする設計思想。Sassのimport機能を使う事でレイヤーに分けられたスタイルを使いたいものだけインポートし、適用出来るなどその設計の力を十二分に引き出せるという事ですね。


##まとめ

ここまででCSSの設計思想とそのポテンシャルを引き出すSassを学んできました。これで大分モダンなCSSが書けそうですね。

でもまだまだ入口を見ただけ。フロントエンジニアの奥は深い。CSSについては少し経験を積んだ上で、CSS設計とSassを利用した際の具体的な取り組み方などについてお話したいと思います。

それではまた！



###参考にしたサイト

https://www.willstyle.co.jp/blog/1276/
https://qiita.com/cotolier_risa/items/33ca1dcd700927dd7ba0
https://qiita.com/manabuyasuda/items/5d83a5516051cc58a274
https://www.tam-tam.co.jp/tipsnote/html_css/post10205.html