Shopifyでも使われているSass（SCSS）について簡単にまとめてみた

# ■ 概要

なぜ、この記事を書くことになったのかという経緯を少しだけ。（Sassについての解説だけ知りたい方は読み飛ばしてください。）

普段、主に Shopify で ECサイトの構築を行っています。

Shopify は、ノーコードで簡単に構築できる点が最大の魅力です。
しかし、クライアントのデザインの要望に完璧に応えるには、やはりコーディングが必要になります。

Shopify の見た目の部分は、基本的には CSS で書かれていますが、SCSS で書かれているテーマ（Narrativeなど）も見かけます。

現在、Shopify は SCSS でのテーマの開発を非推奨としていますので、これから SCSS が記述されたテーマはなくなっていくと思います。
しかし、現状 SCSS で書かれたテーマが存在するということは事実で、見た目の部分を編集する際には SCSS を読まなければいけません。

そこで、 SCSS について何も知らないわけにはいかないと思い、この記事を執筆しています。

参考にしたのは、[Sassの公式サイト](https://sass-lang.com/)です。

簡単に Sass について解説していきます。内容は基本的に公式の和訳です。

それではいきましょう！




# ■ Sassとは

![Sass公式TOP](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/748775/84748bd4-1334-f052-5ca0-10110e65b849.png)

SCSS が Sass の一種だということはなんとなく知っていたので、まずは Sass についての解説から。

そもそも、Sass とは何なのでしょう？

Sass 公式TOPの説明を和訳したものがこちら。

> Sass は世界で最も成熟し、安定し、かつ強力なプロフェッショナルグレードの CSS 拡張言語です。

この説明からわかるのは、Sass は CSS の拡張言語なのだということだけです。



## ▶︎ Sassの特徴について知ろう

![Sassの特徴6つ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/748775/3a91f96f-f31a-e2f9-3c7b-58bd95839031.png)


Sass の特徴が、公式サイトTOP で6つ紹介されていたのでそれぞれまとめてみました。



### ① CSS Compatible （ CSS との互換性）

公式の解説がこちら。

> Sass はすべてのバージョンの CSS と完全に互換性があります。私たちはこの互換性を真剣に考えていますので、利用可能な CSS ライブラリをシームレスに利用することができます。

つまり、Sass はすべての CSS に対応しているからすごいということです。


### ② Feature Rich （豊富な機能）

公式の解説がこちら。

> Sass は他のどの CSS 拡張言語よりも多くの機能と能力を誇っています。Sass のコアチームは、それに追いつくためだけでなく、先を行くために絶え間ない努力をしてきました。

つまり、Sass の開発者たちがすごく頑張っているから、たくさんの機能があるよということです。


### ③ Mature （成熟している）

公式の解説がこちら。

> Sass は約14年間、愛すべきコアチームによって積極的にサポートされてきました。

つまり、長い間使われ続けている実績があるということですね。


### ④ Industry Approved （業界で認められている）

公式の解説がこちら。

> 業界では、何度も何度も何度も、CSS の拡張言語として Sass が選ばれています。

つまり、みんな使っていて、評価されているよということです。


### ⑤ Large Community （大規模なコミュニティ）

> Sass は数社のテック企業と数百人の開発者からなるコンソーシアムによって積極的にサポートされ、開発されています。

つまり、大きな開発者コミュニティがあり、それにより積極的なサポートと開発がされているよということです。


### ⑥ Frameworks （フレームワーク）

> Sass を使って構築されたフレームワークは無限にあります。Compass, Bourbon, Susy などがあります。

つまり、たくさんのフレームワークがあるよということです。


これらの特徴全てをまとめると、Sass すごいよということです。




# ■ Sass (SCSS) の基本

Sassの何がすごいのかわかったようでわからない感じですが、結局何ができるのでしょうか？

![Sass Basicsのページ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/748775/90d480d5-a338-827a-b77d-c2878d228d18.png)

ここからは[Sass公式の「Sass Basics」のページ](https://sass-lang.com/guide)を参考にSassの基本についてまとめていきます。

まず、前提としてSassを使う利点です。
それは、「CSSにはない機能を使ってCSSを書くことができる点」です。

このページで紹介されているSassの機能は以下の通りです。

* Variables
* Nesting
* Partials 
* Modules
* Mixins
* Extend/Inheritance
* Operators

これも前提条件として、Sass をブラウザは理解することができません。そのため、ブラウザで使用するためには、Sass を CSS にコンパイルする必要があります。

Sass をコンパイルするもっとも直接的な方法は、ターミナルで行うことです。
Sass をインストールすると `sass`コマンドが使えるようになり、この`sass`コマンドによって Sass を CSS にコンパイルすることができます。

これらの情報を踏まえた上で、Sass（SCSS）の具体的な機能や書き方、コンパイル後の CSS はどうなるのかについてみていきましょう。


## ▶︎ Variables (変数)

Sass では、変数を使用することができます。
変数を使用することで、スタイルシート全体で再利用したい情報を保存しておくことができます。

色やフォントなど再利用したいと思う CSS の値を格納し、必要な時に変数名でアクセスします。

Sass は、`$`マークを使用して変数定義を行います。

```.scss:SCSS
$font-stack:    Helvetica, sans-serif;
$primary-color: #333;

body {
  font: 100% $font-stack;
  color: $primary-color;
}
```

```.sass:Sass
$font-stack:    Helvetica, sans-serif
$primary-color: #333

body
  font: 100% $font-stack
  color: $primary-color
```

Sass のコードは`{}`や`;`がない分スッキリしていますね。

コンパイル後の CSS ファイルがこちらです。

```.css:CSS
body {
  font: 100% Helvetica, sans-serif;
  color: #333;
}
```

上記の例のように`$primary-color: #333`で`$primary-color`という変数を定義し``#333という色を代入しています。
定義した変数は、`body`セレクタ内の`color`プロパティの値として使用しています。使用する際も`$primary-color`のように`$`マークを使用します。

これは、ブランドカラーなどを取り扱う際に非常に便利で、サイト全体で一貫性を保つことができます。


## ▶︎ Nesting （入れ子） 

Sass を使うと、HTMl のような視覚的なネスト（入れ子）構造を使用することができます。CSS には、このネストがないため、視覚的に不利です。

ただ、ネストできるからと言って、階層が深くなるとコンパイル後に過剰に就職された CSS となり、メンテナンス性が下がるため、注意が必要です。

以下の例は、典型的なサイトのナビゲーションのサンプルです。

```.scss:SCSS
nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li { display: inline-block; }

  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
  }
}
```

```.sass:SCSS
nav
  ul
    margin: 0
    padding: 0
    list-style: none

  li
    display: inline-block

  a
    display: block
    padding: 6px 12px
    text-decoration: none
```

コンパイル後の CSS ファイルがこちらです。

```.css:CSS
nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
nav li {
  display: inline-block;
}
nav a {
  display: block;
  padding: 6px 12px;
  text-decoration: none;
}
```

`ul`, `li`, `a`タグが、`nav`セレクタの中にネストされています。
ネストされたセレクタは、コンパイル後の子孫結合子の形で記述されます。

ネストされることで、HTML の構造とリンクし CSS の可読性が向上します。


## ▶︎ Partials （パーシャル化）, Modules （モジュール化）

大規模なウェブサイトになると、CSS ファイルの記述は必然的に多くなり、管理が大変になっていきます。

Sass では、ファイルを分割しモジュール化することができ、それらをインポートして使用することができます。
そのため、CSS と比べ保守の観点から優れています。

これが、特徴の一つであるモジュール化です。JavaScript のような挙動なので、難しくはないですね。

モジュールは、`@use`を用いることでインポートして使用することができます。
その際、ファイル内の変数や関数には、ファイル名に基づいた名前空間で参照することができます。

また、パーシャル化とは、ファイルの先頭に`_`（アンダースコア）を書くことで、CSS として書き出されないようにする手法のことです。
例えば、`_partial.scss`という名前のつけられた SCSS ファイルは、コンパイル後に書き出されることはありません。

変数定義をするファイルは分けて作成しインポートすることで、コードの管理が楽になります。また、そのようなファイルは、パーシャル化することで CSS ファイルとして書き出されないようにしましょう。

```_base.scss
$font-stack:    Helvetica, sans-serif;
$primary-color: #333;

body {
  font: 100% $font-stack;
  color: $primary-color;
}
```

```style.scss
@use 'base';

.inverse {
  background-color: base.$primary-color;
  color: white;
}
```

これをコンパイルしたファイルがこちらです。

```style.css
body {
  font: 100% Helvetica, sans-serif;
  color: #333;
}

.inverse {
  background-color: #333;
  color: white;
}
```

`_base.scss`は、ファイル名の先頭に`_`がついているため、コンパイルされることはありません。
`_base.scss`に記述されたコードは、`@use 'base';`によりインポートされています。Sass のインポートには、拡張子は必要ありません。
インポートしたファイル内の変数に参照する際は、`base.$primary-color`のように`ファイル名.変数名`と書きます。

Sass の場合のサンプルコードはこちらです。

```_base.sass
$font-stack:    Helvetica, sans-serif
$primary-color: #333

body
  font: 100% $font-stack
  color: $primary-color
```

```sytle.sass
@use 'base'

.inverse
  background-color: base.$primary-color
  color: white
```

コンパイル後のコードは、SCSS をコンパイルした CSS ファイルと同じコードになります。



## ▶︎ Mixins （ミックスイン）

mixin は、Sass で使える関数のようなものです。
`-webkit`や`-moz`などのベンダープレフィックスが必要な場合、コードが冗長になるため少し面倒です。
mixin はそのような時に、サイト全体で再利用したい CSS 宣言をグループ化することができます。

また、mixin には引数を渡すことができます。使い方は、JavaScriptと同じような感じです。

`@mixin ミックスインの名前 (引数)`のように定義します。定義した mixin は、`@include`により使用することができます。

`transform`を例にした mixin の使い方です。

```.scss:SCSS
@mixin transform($property) {
  -webkit-transform: $property;
  -ms-transform: $property;
  transform: $property;
}
.box { @include transform(rotate(30deg)); }
```

コンパイル後の CSS のコードがこちらです。

```.css:CSS
.box {
  -webkit-transform: rotate(30deg);
  -ms-transform: rotate(30deg);
  transform: rotate(30deg);
}
```

SCSS ファイルの冒頭で、`transform`という名前を持つ mixin を作成しています。`transform`mixin は、`$property`を引数として受け取り、 mixin の`{}`の中で使用されます。これにより`transform`プロパティを使って要素に変化を加えたい場合は、`@include transform (rotate(30deg))`のように1行で済みます。また、引数の値を変えることで動きを変更することもできます。

Sass の場合は以下のようなコードになります。
定義と使用する際の記述が若干異なります。定義には`=`、呼び出しには`+`を使います。

```.sass:Sass
=transform($property)
  -webkit-transform: $property
  -ms-transform: $property
  transform: $property
.box
  +transform(rotate(30deg))
```

コンパイル後の CSS コードは、SCSS をコンパイルして出来上がるコードと同じです。


## ▶︎ Extend/Inheritance （拡張・継承）

継承（Extend）を使うことで、セレクタから別のセレクタに CSS プロパティのセットを共有することができます。

`@expand セレクタ名`と書くことで継承することができます。

サンプルコードを見てみましょう。

```.scss:SCSS
/* %message-shared が拡張されているためコンパイルされます。 */
%message-shared {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

// %equial-heights は拡張されていないためコンパイルされません。
%equal-heights {
  display: flex;
  flex-wrap: wrap;
}

.message {
  @extend %message-shared;
}

.success {
  @extend %message-shared;
  border-color: green;
}

.error {
  @extend %message-shared;
  border-color: red;
}

.warning {
  @extend %message-shared;
  border-color: yellow;
}
```

上記のコードをコンパイルすると、以下のような CSS ファイルが書き出されます。

```.css:CSS
/* %message-shared が拡張されているためプリントされます */
.message, .success, .error, .warning {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

.success {
  border-color: green;
}

.error {
  border-color: red;
}

.warning {
  border-color: yellow;
}
```

サンプルコードで出てきた`%message-shared`のように`%`から始まるセレクタをプレースホルダークラス（プレースホルダーセレクタ）と言います。
プレースホルダークラスは、拡張された際にのみ表示される特別なタイプのクラスです。拡張により使用しなかったプレースホルダークラスは、コンパイル後に書き出されることはありません。
実際に、`%equal-heights`は拡張されなかったため、CSS ファイルには書き出されていません。

もちろん、プレースホルダークラス以外のクラスも継承することができます。

プレースホルダークラスは Sass ファイルにのみ記述するクラスなので、HTML 要素に複数のクラスを記述する必要がなくなります。

コードを上から順に見ていきます。

まず、`%message-shared`というプレースホルダークラスが記述してあります。
このプレースホルダークラスは、`@extend %message-shared;`と記述することで、`.massage`, `.success`, `.error`, `.warning`セレクタの中で継承されています。

コンパイルされた CSS ファイルを見てみると、継承した全てのセレクタに同じプロパティがCSSが記述してあります。

継承を使うことで、同じコードを簡単に再利用することができます。


Sass の場合は以下のように記述します。

```.sass:Sass
/* This CSS will print because %message-shared is extended. */
%message-shared
  border: 1px solid #ccc
  padding: 10px
  color: #333


// This CSS won't print because %equal-heights is never extended.
%equal-heights
  display: flex
  flex-wrap: wrap


.message
  @extend %message-shared


.success
  @extend %message-shared
  border-color: green


.error
  @extend %message-shared
  border-color: red


.warning
  @extend %message-shared
  border-color: yellow
```

コンパイル後の CSS ファイルは、SCSSファイルと同じコードが書き出されます。



## ▶︎ Operators （四則演算）

Sass では、`+`, `-`, `*`, `/`, '%'などの標準的な数学的演算子を使用することができます。

サンプルコードでは、`aside`と`article`の幅を計算するための簡単な計算をしています。

```.scss:SCSS
.container {
  width: 100%;
}

article[role="main"] {
  float: left;
  width: 600px / 960px * 100%;
}

aside[role="complementary"] {
  float: right;
  width: 300px / 960px * 100%;
}
```

```.sass:Sass
.container
  width: 100%


article[role="main"]
  float: left
  width: 600px / 960px * 100%


aside[role="complementary"]
  float: right
  width: 300px / 960px * 100%

```

コンパイル後のコードがこちらです。

```.css:CSS
.container {
  width: 100%;
}

article[role="main"] {
  float: left;
  width: 62.5%;
}

aside[role="complementary"] {
  float: right;
  width: 31.25%;
}
```

`960px`をベースにした非常にシンプルな`float`グリッドです。
Sass の Operators を使うと、ピクセル値を取得してパーセンテージ変換すると言ったことを、それほど手間をかけずに行うことができます。

これに関しては、CSS にも `calc`があるのでどうなのかという話ですが笑
Sass の方がスッキリしてはいますね。




# ■ まとめ

Sass について軽くまとめてみましたが、プログラミングチックな CSS ということで面白かったです。

これから Shopify の SCSS と格闘したいと思います。

最後まで読んでいただき、ありがとうございました。