Sassに入門したので覚えておきたいと思ったことメモ

 勉強したり実際に使ってみたりしたけど、三歩歩けば全てを忘れるトリ頭なので備忘録として。
 Sassは入門したてで右も左もわからない状態なので、間違い等ございましたら、やさしく指摘して頂けるとうれしいです。（╹◡╹）

#記事の概要

 今回の記事ではSassに入門したてのひよっこが実際に色々試してみた中で、「これいいじゃん」と思った機能について、nヶ月後に見返してもさくっと思い出せるように要点と簡単な使い方について書いていきます。
 まずは小さくスタートしてみようということで、今回は基本的な要素だけを利用してあれこれやってみました。

---

#Sassとは?

ここではSassとは何か、またSassを使うと何が嬉しいのか、ということについて書いていきます。
 Sassとは「Syntactically Awesome Style Sheets」の略称であり、「構文的に**イカした**スタイルシート」という意味となります。読み方としては「サス」が主流になっているようです。
 以下では具体的にSassがどうイカしているか、ということについて触れていきます。


###Sassを使うと何が嬉しいの？

Sassのメリットについては巷でも既に色々と書かれていますが、ここでは個人的にいい感じだなと思った機能について紹介させて頂きます。

* CSSからお手軽に始められる
* ネストでコードが見やすくなる
* ミックスインで共通部品を使いやすい名前で使いまわせる
* 継承でモジュールの派生形をばしばし作れる
* 変数でベースの値を一括管理できる
* リクエストを気にせずフォルダ構成を自由にできる

 各種機能について一つ一つ見ていきたいと思います。

---

#CSSからお手軽に始められる
 「構文的にイカした」スタイルシートってことはCSSとは別物なんだろうし、学習コスト高そう...と思っていましたが、SassyなCSS、というSCSS形式での記法がサポートされたことにより、CSSをベースにSassを使えるようになりました。
 これにより、既存のCSSについてちょっとだけネストを使ってみるとか、ミックスインでまとめてみる、といったようにCSSファイルをベースに小さな機能から拡張していくことができます。
 
 SCSSファイルはさくっとCSSに変換するための機能が色々とそろっているので、これまでCSSをごりごり書いていくのと同じ感じでコーディングを進めることができます。これはありがたいですね。

---

ここからの機能については、実際にコードがどう変わるか、ということを見た方が分かりやすいかと思うので、HTML、実際の画面、そしてSassのコードをあわせて見ていきたいと思います。

今回はツイッタークローン風のモックアップ画面をSassの練習がてら書いたものを使用していきます。コードは実際の画面とセットでこの記事でも載せてはいきますが、[GitHub](https://github.com/a-pompom/twitter_clone_practice)にも置いてありますので、よしなに。

---

#ネストでコードが見やすくなる

 まずはネストについて見ていきたいと思います。
通常CSSでヘッダなりログイン画面なり何らかの画面のパーツについてスタイルを適用する際、要素が複雑になるにつれどんどんパーツごとのスタイルが縦に長くなっていきます。
こうなると、ある要素のスタイルを追うためにスクロールする手間が生じてしまいますし、そもそも可読性もあまりよくありません。

例として、フォローユーザ要素を見てみます。フォローユーザ要素の画面イメージとHTMLは以下のようになります。



![follow.png](https://qiita-image-store.s3.amazonaws.com/0/307733/eb52fac0-7cfa-050c-f202-ca359cd0ab94.png)


 
```html:follow.html

<!-- フォロー欄 -->
<div class="follow">
  <ul class="follow__user">
    <li>
      <ul class="follow__user__content">
        <li class="icon--middle"><i class="fas fa-smile"></i></li>
        <li class="button--follow">フォロー中</li>
      </ul> 
    </li>

    <li class="follow__user__content">ユーザ名<i class="fas fa-heart"></i></li>
    <li class="follow__user__content">ユーザID</li>
    <li class="follow__user__content">Nulla pellentesque hendrerit erat, luctus egestas arcu ultrices ut. In hac habitasse platea dictumst. </li>
  </ul>
</div>

```

このぐらいの深さのHTMLでもCSSでクラスを一つずつ拾って書いていくとどんどん縦に長くなっていくので、HTMLとCSSの構造が対応せず、コードが読みづらくなってしまいます。

これをSassで書くと以下のようになります。

```scss:follow.scss
.follow {
    width: 70%;
    @include flex-table;
    align-items: center; 
    line-height: 1.6;
    
    &__user {
        width: 25%;
        height: 200px;
        background-color: white;
        margin-left: 20px;
        padding-left: 10px;
        
        //ユーザ名は太字で強調
        & > :nth-child(2) {
            font-weight: bold;
        }
        
        &__content {
            @include flex-left;
            padding-left: 0;
            
            //フォロー中ボタン
            & > :last-child {
                //フォロー中ボタンはアイコンに対して中央右端に配置するためmarginを設定
                margin: auto 10px auto auto;
            }
        }
    }
}

```

細かい記法については後々見ていきますので、今回は階層構造に着目したいと思います。
 ぱっと見た感じ、HTMLと階層構造が似たような感じになっているかと思いますが、Sassでは親要素のブロックの中に子要素を記述することができます。
これにより、HTMLとの対応関係からスタイルを定義した箇所がどの辺りに存在するか直感的に把握しやすくなります。


###「＆」とはなんぞや

「&」記号が随所に記述されていますが、これは親要素を参照するためのキーワードのようなものです。
この記号の便利なところは、子要素のクラス名を簡潔に書けるようになることです。コンパイル後のCSSでは、「&」が親要素へと自動的に変換されます。
 また、親クラスの参照だけでなく「:hover」などの擬似要素に対しても使うことができ、クラスとの関係をより視覚的に分かりやすく捉えることができます。
 文章だけではイメージが掴みづらいので、実際にコンパイル結果のCSSを見てみましょう。



```css:style.css

.follow {
  width: 70%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  line-height: 1.6;
}

.follow__user {
  width: 25%;
  height: 200px;
  background-color: white;
  margin-left: 20px;
  padding-left: 10px;
}

.follow__user > :nth-child(2) {
  font-weight: bold;
}

.follow__user__content {
  display: flex;
  justify-content: flex-start;
  padding-left: 0;
}

.follow__user__content > :last-child {
  margin: auto 10px auto auto;
}

```

「&」記号が親要素のクラス名へ変換されたことが分かります。
 また、変換後のCSSからSassを利用したスタイルとの違いがより見やすくなっているかと思います。

---

###「＆」について：余談

「&」記号は便利な反面考えなしに乱用し過ぎると、要素のスタイルを特定するのに時間を要してしまうことになります。これを防ぐためには、モジュールごとにファイルを分割し、親要素が明確である状態を保てるよう記述していくとよいかと思います。
 CSSのファイル分割や親子関係を明確にするためのクラスの命名についてSMACSSやBEMなどがありますが、そのへんについてはまた別の機会で触れたいですね。別の機会をちゃんと作れるように頑張りたいです。

---

#ミックスインで共通部品を使いやすい名前で使いまわせる

※コメントでミックスインという言葉のニュアンスについて指摘を頂いたので追記しました。

 続いて、ミックスインについて見ていきます。「mix」 + 「in」は、字面上は混ぜ合わせて一つにする、という意味合いになります。
 しかし、プログラミングの世界での「Mixin」はその成り立ちから、字面とは少し違ったニュアンスを有しています。ここでは、ミックスインという言葉をプログラミング上で初めて使うようになったと言われているFlavorsについて少し見ていきたいと思います。

 以下、引用。

---

> Flavorsは1978年頃にLisp Machine Lispに導入されたオブジェクト指向システムです。
> LispマシンはPARCのAltoを手本としたシステムですが、IOやウィンドウシステムにFlavorsというオブジェクト指向システムを全面的に採用し成功を収めました。

>1976年あたりにSmalltalkのOOPを知ったMITのLisp界隈の人達の間では、オブジェクト指向システムを作ったり、そのような構成法でプログラムを書いたりするのが流行したそうですが、その中からFlavorsのようなものが登場してきたようです。


 >Flavorsといえば、アイスクリームの話が有名ですが、アイスクリーム屋さんでは、ベース(デフォルト)のフレーバーをVanillaとし、そこにトッピングで色々なフレーバーを追加していくことを、Mixinと呼んでいたそうで、その構成法と用語は、そのままFlavorsの用語ともなっています。

> * flavor (class)
> * vanilla flavor (base class)
> * mixin (多重継承の作法)

 引用ここまで。[参考](https://g000001.cddddr.org/3691315338)

 Lispの話が出てきていますが、ここで重要なのは、プログラミングの世界での「Mixin」は混ぜ合わせ一つにする、という「mix」とは異なり、ベースのバニラアイスへトッピングを**混ぜ込む**というニュアンスを表している、ということです。
 文字だけだといまいちピンとこない場合は、「food mix」、「ice mixin」で画像検索し、結果を比較してみると、「混ぜ合わせる」ことと「混ぜ込むこと」の違いが掴めるかと思います。

---

 Sassではミックスインにより、よく使う汎用的な機能を引数を利用して形を変えながら使い回すことができるようになります。
 引数を利用したミックスインはレスポンシブデザインを考える際に真価を発揮するみたいなのですが、そこまで手をつける気力がなかったので、今回は割愛しています。
 バックエンド部分もある程度実装したらレスポンシブデザインをSassで頑張りたいと思います(願望)

---

###ミックスインの基本

 実際のミックスインの使い方について見ていきます。
 ミックスインは「@mixin ミックスイン名」と記述し、共通化したい要素をブロックで囲うことで定義されます。汎用的な要素を共通化する際に利用するので、小規模な開発ではミックスインを一まとまりとして一ファイルに定義しておくと管理がしやすくなるかと思います。
 今回の場合では「clearfix」と「flex-box」をミックスインでまとめました。まとめることにより、各画面で利用しているflex-boxをレイアウト方法に応じてミックスイン名で呼び出すだけで使えるようになります。
実際のミックスインのコードは以下のようになります。

```scss:mixin.scss
//ミックスイン要素はCSSへ出力されないので行コメントを利用


//clearfix

@mixin clearfix {
    content: '';
    display: block;
    clear: both;
}


//flex-box
@mixin flex-center {
    display: flex;
    justify-content: center;
}

@mixin flex-right {
    display: flex;
    justify-content: flex-end;
}

@mixin flex-left {
    display: flex;
    justify-content: flex-start;
}

@mixin flex-between {
    display: flex;
    justify-content: space-between;
}

@mixin flex-table {
    display: flex;
    flex-wrap: wrap;
}
``` 

例として、ヘッダ要素から実際にミックスインを利用しているスタイルについて見ていきます。
 ヘッダは要素が横並びになっており、左側がコンテンツ情報、右側がユーザ情報を表しています。

<img width="1433" alt="head.png" src="https://qiita-image-store.s3.amazonaws.com/0/307733/e95291c3-1dae-baf0-5cfe-36a75686dba5.png">

 これをHTMLで記述していくと以下のようになります。

```html:header.html
<header class="header">
  <ul class="header__nav">
    <li><a href="#" class="link--header">
      <i class="fas fa-home"></i>ホーム</a></li>
    <li><a href="notification.html" class="link--header">
      <i class="fas fa-bell"></i>通知</a></li>
    <li><a href="#" class="link--header">
      <i class="fas fa-envelope"></i>メッセージ</a></li>
    <li>
      <form class="header--nav-search">
        <input type="text">
        <a href="search.html" class="link--header">
          <i class="fas fa-search"></i> 検索</a>
      </form>
    </li>
  </ul>
  <div class="header__sub">
    <a href="user.html" class="link--header"><i class="fas fa-smile"></i></a>
    <a href="login.html" class="button--exit">ログアウト</a>
  </div>
</header>
```

「header__nav」がコンテンツ、「header__sub」がユーザ情報と対応しています。色々と要素が記述されていますが、コンテンツ用のulとユーザ用のdivが存在している、というのが大枠となっています。
 このHTMLから画像のような横並びレイアウトへスタイリングするためにSassを利用するとコードは以下のようになります。 　

```scss:header.scss
.header {
    width: 100%;
    height: 40px;
    background-color: #fff;
    @include flex-center;
    
    &__nav {
        width: 40%;
        @include flex-between;
        line-height: 1.0;
    }
 
    &__sub {
        width: 16%;
        @include flex-between;
        margin-left: auto;
        line-height: 2.0;
    }
}

```

大元のヘッダ、中身のそれぞれの要素でflex-boxを利用していますが、ミックスインにより、コードがシンプルにまとまるようになっているかと思います。
呼び出し先で、定義したミックスインを使う場合は、「@include ミックスイン名」と記述することでミックスインのブロック内のスタイルが記述箇所内へ埋め込まれます。これは、コンパイル結果のCSSを見て頂くとより明確になります。


```css:style.css
/*------------------------------*/
/*HEADER*/
/*------------------------------*/
.header {
  width: 100%;
  height: 40px;
  background-color: #fff;
  display: flex;
  justify-content: center;
}

.header__nav {
  width: 40%;
  display: flex;
  justify-content: space-between;
  line-height: 1.0;
}

.header__sub {
  width: 16%;
  display: flex;
  justify-content: space-between;
  margin-left: auto;
  line-height: 2.0;
}
```
 ミックスインの定義ファイルで記述したスタイルがそのまま各所に埋め込まれていることが分かります。

　　ミックスインは前述の通り、共通部分がミックスイン名で管理できるようになるだけでなく、変更が生じた際の影響範囲も抑えられる、というように多くのメリットがあるので、まずは引数なしから使ってみて少しずつ慣れていくようにするとよいかと思います。
 
 次はミックスインとよく比較される継承について見ていきます。

---

#継承でモジュールの派生形をばしばし作れる

 ミックスインとは別に共通部を再利用できる機能として継承があります。
 「@extend 継承元」とすることで継承元のスタイルをそのまま利用したり、上書きしたりという使い方ができます。CSSで継承というとinheritの方が耳馴染みがあるかもしれませんが、オブジェクトをあれこれする世界ではextendを継承と解釈するのが一般的のようです。

 さて、継承はミックスインと記述自体はよく似ているので、まずは例を見ていきましょう。
 今回は様々な形で利用されているボタンモジュールについてのスタイルに着目します。何はともあれ、まずは継承を利用したSassのコードを見るのが早いかと思います。

```scss:button.scss
%button {
    //文字のスタイル
    text-decoration: none;
    text-align: center;
    font-size: 1.3rem;
    line-height: 1.5;
    color: #fff;
    
    //ボタンの枠のスタイル
    border-radius: 5px;
    
    //ボタンの配置のスタイル
    display: inline-block;
    margin-right: 20px;
    margin-top: 5px;
    cursor: pointer;
    
    //擬似要素
    &:hover {
        opacity: 0.8;
    }
}

.button--save {
    @extend %button;
    display: block;
    width: 250px;
    height: 50px;
    margin: 30px auto;
    font-size: 1.5rem;
    background-color: $BASE_COLOR;
}

.button--nav {
    @extend %button;
    width: 100px;
    height: 30px;
    background-color: $BASE_COLOR;
}

...(以下省略)

```

最初に見慣れないものが出てきましたが、「%」はプレースホルダーセレクタというように呼ばれ、ここに定義されたスタイルはCSSには出力されないものとなります。
 こう書くとミックスインとさほど違いがないように見えますね。しかし、ミックスインと継承の違いは出力されるCSSへと表れます。


```css:style.css
/*------------------------------*/
/*BUTTON                        */
/*------------------------------*/
.button--save, .button--nav, .button--exit, .button--edit, .button--follow {
  text-decoration: none;
  text-align: center;
  font-size: 1.3rem;
  line-height: 1.5;
  color: #fff;
  border-radius: 5px;
  display: inline-block;
  margin-right: 20px;
  margin-top: 5px;
  cursor: pointer;
}

.button--save:hover, .button--nav:hover, .button--exit:hover, .button--edit:hover, .button--follow:hover {
  opacity: 0.8;
}

.button--save {
  display: block;
  width: 250px;
  height: 50px;
  margin: 30px auto;
  font-size: 1.5rem;
  background-color: #b2f0ff;
}

...(以下省略)

```

 ミックスインとは明らかに結果が異なっていることが分かるかと思います。継承では継承元のスタイルは一箇所にのみ記述され、継承先でセレクタがまとめられています。
 記述量が減るんだし、引数とか使わないなら全部継承で良さそうじゃん、というように見えますが、継承を利用する際には少し注意が必要です。

---

###継承とミックスインの使い分けについて　

継承では記述量を減らすことはできますが、汎用的な機能を継承元にしてしまうと、大量のクラスから継承されてしまい、セレクタの数が凄まじいことになります。
 一方、ミックスインは今回のボタンの例で利用するとベースの部分がCSSに何度も記述され、多くの重複部分が生じてしまいます。

 この二つの使い分けについては、オブジェクト指向の継承でおなじみの**「is a関係」**を考えると分かりやすいです。
 例えば、「青いボタン は ボタン」という関係は成り立ちますが、「サイドメニュー は clearfix」というような関係は成り立ちません。
 このように、継承はベースとなるモジュールの派生形、ミックスインは関係性によらず共通部品として広く使われる機能、と使い分ければ可読性を保てるかと思います。
 
---

#変数でベースの値を一括管理できる

 今回の例ではあまり使いこなせていませんが、変数についても触れておきたいと思います。
 変数は「$変数名: 値」という形式で定義され、主には画面上のカラー要素や、画像要素を読み込む際のパスなどで利用されます。

 ミックスインは処理のまとまりを共通化していたのに対し、変数は特定の値を共通化することで、変更が生じた際の影響範囲を抑える役割を持ちます。
 とは言ってもまだ全然使いこなせていないので、レスポンシブ対応の実装をする時間をちゃんと作りたいですね。頑張りたい。
  
---
  
#リクエストを気にせずフォルダ構成を自由にできる

 最後はフォルダ構成について見ていきたいと思います。
 通常CSSはモジュールなどの単位でファイルを分割するとリクエスト数が増えるというデメリットが存在します。一方、Sassさんには全てのモジュールを統合し、一つの「style.css」ファイルへと変換してくれる素敵機能が存在します。
 この機能は「partial」と呼ばれ、SCSSファイル名の先頭に「_」をつけることで有効になります。　partialが適用されたSCSSファイルはコンパイルの際にCSSファイルへの変換の対象外となります。　
 つまり、大元の「style.scss」以外のファイルでpartialを利用し、「style.scss」で一括でインポートしてあげれば最終的な出力結果は一つのCSSファイルとなります。

 各種SCSSファイルのインポート及び実際のフォルダ構成は以下のようになります。

```scss:style.scss
$BASE_COLOR: #b2f0ff;

//ベース部分
@import "base/base";
@import "base/mixin";
@import "layout/layout";


//小モジュール    
@import "simple_module/button";
@import "simple_module/field";
@import "simple_module/link";
@import "simple_module/icon";

//画面用モジュール
@import "module/header";
@import "module/post";
@import "module/login";
@import "module/home";
@import "module/user";
@import "module/follow";
@import "module/notification";
@import "module/search";
```

<img width="169" alt="d.png" src="https://qiita-image-store.s3.amazonaws.com/0/307733/88fa4c7d-c9d0-540d-466f-9d8e891d1593.png">

インポートの際には「@import "SCSS名"」と記述します。また、拡張子については省略して記述することもできます。
 このようにstyle.scssを記述した状態でコンパイルを行うと、一つのstyle.cssへ変換してくれます。

---

#まとめ

 Sassの基本的な機能を利用してみて「これはいい」と思った機能についてざっくりとまとめました。
 まだまだ使いこなせていない機能もたくさんありますが、基本だけでもCSSの設計手法なんかと組み合わせてみることで、だいぶスタイル部分のコードが読みやすくなったんじゃないかな〜と...思いたい。
 個人的にはSassさんのイカしっぷりに惚れ込んだので今後も使っていきたいと思います。

 とりあえずツイッター風のアレをちゃんと投稿とかフォローとかできるようにあれこれ作り込んでいかないといけないので、レスポンシブ対応でまたSassさんと戯れられるよう頑張りたいですね_:(´ཀ`」 ∠):


---

#参考

Sassを勉強する際に参考になったもの

[Web制作者のためのSassの教科書](https://www.amazon.co.jp/Web%E5%88%B6%E4%BD%9C%E8%80%85%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AESass%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E6%94%B9%E8%A8%822%E7%89%88-Web%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%81%AE%E7%8F%BE%E5%A0%B4%E3%81%A7%E5%BF%85%E9%A0%88%E3%81%AECSS%E3%83%97%E3%83%AA%E3%83%97%E3%83%AD%E3%82%BB%E3%83%83%E3%82%B5-%E5%B9%B3%E6%BE%A4-%E9%9A%86/dp/4295002356)

インストールからSassの各種機能まで丁寧に分かりやすく解説してくれています。解説サイトなどもたくさん出回っていますが、本から体系的に学ぶと頭の中も整理されやすくなるのでおすすめです。

[Web制作者のためのCSS設計の教科書](https://www.amazon.co.jp/Web%E5%88%B6%E4%BD%9C%E8%80%85%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AECSS%E8%A8%AD%E8%A8%88%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E3%83%A2%E3%83%80%E3%83%B3Web%E9%96%8B%E7%99%BA%E3%81%AB%E6%AC%A0%E3%81%8B%E3%81%9B%E3%81%AA%E3%81%84%E3%80%8C%E4%BF%AE%E6%AD%A3%E3%81%97%E3%82%84%E3%81%99%E3%81%84CSS%E3%80%8D%E3%81%AE%E8%A8%AD%E8%A8%88%E6%89%8B%E6%B3%95-%E8%B0%B7-%E6%8B%93%E6%A8%B9/dp/4844336355/ref=pd_bxgy_14_img_2?_encoding=UTF8&pd_rd_i=4844336355&pd_rd_r=ab342c6a-1be3-11e9-b46b-c1dbd27410ef&pd_rd_w=1DGKB&pd_rd_wg=H5Tiu&pf_rd_p=a4de75e6-d8f7-4a34-bd69-503ea4866e6c&pf_rd_r=CPZFYFGQXJBSN7JPZQZ7&psc=1&refRID=CPZFYFGQXJBSN7JPZQZ7)

 CSSが苦手過ぎて現実逃避したくなったときに読んだ本です。Sassの存在を知るきっかけにもなりました。
 記事内で少し触れていたSMACSSやBEMについても分かりやすくまとめられているので、　余力があればこちらから読んでみると、Sassを更に使いこなせるのではないかと思います。


[SassMeister](https://www.sassmeister.com/)
 環境構築をしなくてもSassが試せる素敵システムです。書籍やSassの入門コンテンツなどで勉強する際に手を動かしながらやりたい、という方におすすめです。