更新日:
【HTML5・CSS3】 Sassを攻略してコーディングを効率良く書こう!
Sassとは、Syntactically Awesome Style Sheetsの略語で、CSSを拡張したメタ言語のことを指します。
メタ言語とは、言語を定義する為の言語のことです。つまり、SassはCSSのスタイルシート言語の機能を拡張した言語のことです。
1
2
3
4
5
6
7
8
ul {
margin: 1em;
}
li {
padding-left: 1em;
color: red;
}
Sassの一種であるSCSS記法の場合は、下記のように記述します。
1
2
3
4
5
6
7
8
ul {
margin: 1em;
li {
padding-left: 1em;
color: red;
}
}
Sassを使うことで、コードの記述量が減って保守性が高まるので、人為的なミスも減らす事が出来ます。
Sassの基礎情報
この章では、Sassの基礎情報について解説します。
Sassを使った方が良い理由とは?
CSSでもコーディングを行うことが出来ますが、Sassを使った方が良い理由は主に下記の3つあります。
- コードを減らすことが出来る
- 変数や関数を使うことが出来るので、効率的にコードが書ける
- 余計なコードを減らす事で、ミスを減らすことが出来る
Sassを利用するとコードをシンプルにする事が出来るので、保守性が高まり人為的なミスを減らすことが出来ます。CSSと比較しながら、Sassの書き方を解説していきます。
Sassの種類とは?
Sassには「SASS記法」と「SCSS記法」の2種類あります。
それぞれコーディングのルールが違うので、書き方も変わってきます。
下記のCSSの書き方を例にして、SASS記法とSCSS記法で比較していきます。
1
2
3
4
5
6
7
8
9
/* CSSの書き方 */
ul {
margin: 1em;
}
li {
padding-left: 1em;
color: red;
}
SASS記法
SASS記法は、元々SCSS記法が導入される以前にSassで書かれていた記法です。
SCSS記法やCSSで書くよりもコードが簡潔になるので記述量を更に減らすことが出来ます。
1
2
3
4
5
6
7
8
9
/* CSSの書き方 */
ul {
margin: 1em;
}
li {
padding-left: 1em;
color: red;
}
SASS記法の場合は、下記のように記述します。
1
2
3
4
5
6
/* SASSの書き方 */
ul
margin: 1em
li
padding-left: 1em
color: red
CSSと比べると波括弧{}がなくなるのでシンプルなコードにする事が出来ました。書き方のポイントは、下記の3つあります。
SCSS記法
SCSS記法は、スタイルの書き方がCSSと変わらないので、元々CSSを書いていた方はSASS記法よりも入りやすいかと思います。Sass3.0から導入された記法です。
1
2
3
4
5
6
7
8
9
/* CSSの書き方 */
ul {
margin: 1em;
}
li {
padding-left: 1em;
color: red;
}
SCSS記法の場合は、下記のように記述します。
1
2
3
4
5
6
7
8
9
/* SCSSの書き方 */
ul {
margin: 1em;
li {
padding-left: 1em;
color: red;
}
}
CSSと見た目は似ていますが、波括弧{}を入れ子にしている箇所が違います。ulの波括弧{}の中にliの子要素を入れ子構造にする事で、ulを親要素として認識します。
また、現在はSCSS記法の書き方が主流になっているので、ここからはSassの書き方はSCSS記法で説明します。
Sassを導入
Sassを使うには、Ruby本体とSass本体を導入する必要があります。また、導入後にはSassをCSSにコンパイルしなければ、スタイルを反映することが出来ません。
Sassの導入手順とコンパイルについては別記事で解説させて頂いて、今回は「 sassmeisterオンラインエディタ」を使ってSassのコードをCSSに変換された結果を確認していきます。
sassmeisterの使い方
sassmeisterは、リアルタイムでSass,ScssをCSSに変換してくれるサービスです。
これから解説するコードをsassmeisterに貼り付けてもらうとコードの実行結果をリアルタイムで確認する事が出来ます。
下記のリンクよりsassmeisterにアクセスして下さい。
アクセスしたら下記の様な画面が表示されます。
今回はHTMLも使うので、ViewのプルダウンからHTMLを選択します。
左のsassのエディタにコードを書くと、真ん中のエディタにCSSが変換されます。また、HTMLとSassのコードの結果は、下のviewに表示されます。
これから解説されるSassのコードをHTMLと共にsassmeisterで確認してみて下さい。整理しながらコードを理解する事が出来るのでおすすめです。
▼ Sassに関しては、この1冊あれば大丈夫!
基礎から応用的な使い方まで網羅する良書です。HTMLやCSSを触ったことがある方なら理解できる内容になっています。
Sassの基本機能から応用まで学べる!
SCSS記法の様々な使い方
この章では、SCSSの様々な使い方について解説します。
ネストの色々な書き方
SCSS記法の特徴としてネスト構造がありますが、基本的な書き方に加えて他にも覚えておくと便利な書き方があるので解説していきます。
階層構造をネストする
下記のHTMLのコードでは、ulタグを親要素、liタグを小要素の階層になっています。
HTMLの要素やタグを復習したい方は、「HTMLタグと要素」を参考にして下さい。
1
2
3
4
5
<ul class="parent">
<li class="child">テキスト1</li>
<li>テキスト2</li>
<li>テキスト3</li>
</ul>
この様な階層構造は、CSSで書くと下記の様に記述します。
1
2
3
4
5
6
7
.parent {
color: red;
}
.parent .child {
color: blue;
}
これをSCSS記法で書くと、小要素をネストして記述する事が出来ます。
1
2
3
4
5
6
7
.parent {
color: red;
.child {
color: blue;
}
}
プロパティをネストする
階層構造だけではなく、プレフィックスが同じプロパティもネストする事が出来ます。
1
<div class="content">中身</div>
1
2
3
4
5
.content {
background-color: red;
padding-top: 1em;
padding-left: 2em;
}
SCSSで書くと下記の様な構造になります。
1
2
3
4
5
6
7
.content {
background-color: red;
padding: {
top: 1em;
left: 2em;
}
}
paddingの後のコロンの付け忘れに注意しましょう。
アンパサンド(&)を使ってネストする
SCSS記法では、アンパサンドと呼ばれる&
を使ってネストすると、親セレクタを参照する事が出来ます。
例えば、通常CSSでリンクのホバー時に文字の色を変更する場合は、擬似要素を使って以下のコードのように記述します。
1
2
3
4
5
<ul>
<li><a href="#">テキスト1</a></li>
<li>テキスト2</li>
<li>テキスト3</li>
</ul>
1
2
3
4
5
6
a {
text-decoration: none;
}
a:hover { /* ホバー時に色を変更する */
color: green;
}
これをアンパサンド(&
)を使うと、以下のコードのように記述する事が出来ます。
1
2
3
4
5
6
7
a {
text-decoration: none;
&:hover { /* &は親セレクタのaを参照する */
color: green;
}
}
ネストしている&
は、親セレクタのa
を参照してるので、上記の&:hover
はa:hover
となります。
また、アンパサンド&
は、擬似要素以外にも以下のコードのようにBEMが取り入れられたクラス名の場合に効率良く記述する事が出来ます。
1
2
3
4
<form class="form">
<input type="text" class="form__text">
<input type="submit" class="form__button">
</form>
1
2
3
4
5
6
7
8
9
10
.form {
&__text { /* &はformを参照するので form__textになる */
font-size: 18px;
}
&__button { /* &はformを参照するので form__buttonになる */
color: white;
background-color: blue;
}
}
CSSにコンパイル後は以下のコードのようになります。
1
2
3
4
5
6
7
.form__text {
font-size: 18px;
}
.form__button {
color: white;
background-color: blue;
}
sassmeisterで確認すると、以下の動画のようになります。
このように、アンパサンド&
を使うと親セレクタを参照する事が出来るので相性が良いと言われているBEMと合わせて利用すると更に効率良くコーディングする事が出来ます。
BEMについて詳細は、「BEMの使い方」を参考にしてください。
変数の定義
SCSSでは、変数を定義して利用する事が出来ます。
1
2
3
4
5
/* 変数の定義 */
$変数名: 値
/* 変数を使う */
$変数名
変数の定義は、「$変数名: 値」で定義する事が出来きて、定義した変数は「$変数名」で利用出来ます。
メディアクエリのブレイクポイントのサイズやカラーなど共通する値を変数にすると使いまわす事が出来るので便利です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 共通で使うカラーを定義 */
$color-main: #ff00ff;
a{
text-decoration: none;
&:hover {
color: $color-main;
}
&::before {
color: $color-main;
content: "★";
}
}
CSSにコンパイルされると下記の様なコードになります。
1
2
3
4
5
6
7
8
9
10
11
a {
text-decoration: none;
}
a:hover {
color: #ff00ff;
}
a::before {
color: #ff00ff;
content: "★";
}
変数で定義した「#ff00ff」の値がcolorに設定されているのが分かります。
演算
SCSSは、加算(+)、減算(-)、乗算(*)、除算(/)、剰余(%)を使って計算を行うと、コンパイル時に計算結果に変換してくれる便利な機能があります。
1
2
3
4
.box {
height:20px * 2;
width:100px - 20px;
}
上記のSCSSのコードはCSSにコンパイルされると、計算結果がプロパティの値になっている事が分かります。
1
2
3
4
5
.box {
/* プロパティ値が演算結果の値になる */
height: 40px;
width: 80px;
}
※除算だけは丸括弧()で囲むので注意してください。
1
2
3
4
5
/* 除算は丸括弧()で囲む */
.box {
height:20px * 2;
width:(1000px / 3);
}
1
2
3
4
.box {
height: 40px;
width: 333.3333333333px;
}
丸括弧()しなかった場合は「width:(1000px / 3);」がそのまま出力されます。
関数
SCSSでは、文字列や数値や色などを操作するための関数がたくさん用意されています。下記は、数ある中の関数の一部です。
関数 | 概要 |
---|---|
unit($number) | 値から単位を取得する |
mix($color1, $color2, $weight) | 2つの色を混ぜる |
invert($color) | 色を反転させる |
alpha($color) | 色の透明度を取得する |
lighten($color, $amount) | 指定の色を指定した割合だけ明るくする |
指定した2つの色を混ぜる関数mix()を使ってみましょう。
1
<div class="box"></div>
mix()の引数には、混ぜる色2つを指定します。第3引数に割合を指定する事が出来ます。
1
2
3
4
5
.box{
background-color: mix(#000, #fff, 50%);
height: 100px;
width: 100px;
}
第3引数の割合を変える事で色に変化を付けることが出来ます。
この様にSCSSには、便利な関数が沢山提供されています。
1
2
3
4
5
6
7
8
/* 変数で定義 */
$base-color1: #000;
$base-color2: #fff;
.box{
background-color: mix($base-color1, $base-color2, 50%);
/* 中略 */
}
ディレクティブ
「@名前」で指定することの出来る命令をディレクティブと言います。SCSSでは、関数やmixinと呼ばれる様な様々な処理制御にディレクティブが対応します。
これからSCSSの代表的な4つのディレクティブを解説していきます。
- @functionディレクティブ - 自作で関数を定義する事が出来る
- @mixinディレクティブ - スタイル定義を再利用する
- @extendディレクティブ - 定義済みのスタイルを継承する
- @importディレクティブ - 外部のスタイルシートを読み込む
1.@functionディレクティブ
SCSSは、先ほど解説したmix関数の様に提供される関数もありますが、自作で関数を作成することも出来ます。
@functionディレクティブを使って定義します。また、@returnディレクティブを使った戻り値を返します。
1
2
3
4
5
6
7
/* 関数を定義する */
@function 関数名(引数) {
@return 戻り値;
}
/* 関数の呼び出し */
関数名(引数);
簡単な例を見ていきましょう。下記は「引数で指定した値($value) ÷ 2」の結果を返すsample関数を定義しています。
1
2
3
4
5
6
7
@function sample($value) {
@return $value / 2;
}
div {
width: sample(100px);
}
上記のコードがコンパイルされると、下記のようになります。
1
2
3
div {
width: 50px;
}
何度も利用する処理を関数で定義することによって、汎用性があるシンプルなコードになります。
2. @mixinディレクティブ
@mixinディレクティブは、ミックスインとも呼ばれており、スタイル定義を再利用するための仕組みです。@mixinディレクティブでスタイルを定義して、@includeディレクティブで使う場所に埋め込みます。
1
2
3
4
5
6
7
8
9
10
11
/* 定義 */
@mixin common-box {
background-color: #222;
color: #eee;
}
.menu {
/* 定義したミックスインを埋め込み */
@include common-box;
padding: 10px;
}
上記のコードをCSSでコンパイルすると下記の様になります。includeしたスタイルが.menuとして挿入されていることが分かります。
1
2
3
4
5
6
.menu {
background-color: #222;
color: #eee;
padding: 10px;
}
@mixinディレクティブは、あらかじめ定義しておいたミックスインを別の場所に再利用する目的で利用されます。
また、@mixinディレクティブは引数でプロパティ値を変えることができます。
1
2
3
4
5
6
7
8
9
10
@mixin box($background-color, $color) {
background-color: $background-color;
color: $color;
}
.menu {
/* 引数に値を指定する */
@include box(#222, #eee);
padding: 10px;
}
3. @extendディレクティブ
@extendディレクティブは、定義済みのスタイルを他のクラスに継承することが出来ます。
以下のコードのように、@extendの後にセレクタ名(.sample
)を引用符で囲まずに指定すると、そのクラスに.sample
のスタイルを継承する事が出来ます。
1
2
/* @extend セレクタ名; */
@extend .sample;
例えば定義済みの.base-content
のスタイルをcontent1
に継承したい場合は、以下のコードのように記述します。
1
2
3
4
5
6
7
8
9
10
11
.base-content {
border: 1px solid grey;
font-size: 20px;
padding: 20px;
width: 200px;
}
.content1 {
@extend .base-content; /* .base-contentを継承する */
border-color: red; /* borderの色だけgreyからredに変更したい*/
}
CSSにコンパイルされると、以下のコードのように同じプロパティを持つスタイルはまとめられます。そして、content1
に独自で定義したborder-color: red
は、個別に出力されます。
1
2
3
4
5
6
7
8
9
10
.base-content, .content1 { /*同じスタイルはまとめられる*/
border: 1px solid grey;
font-size: 20px;
padding: 20px;
width: 200px;
}
.content1 { /*独自で定義したスタイルは個別に記述される*/
border-color: red;
}
このように、@extendディレクティブを使えば同じプロパティはまとめてくれるので、余計な重複コードを出力してしまうという心配がありませんね。
sassmeisterで上記の一連の挙動を確認すると、以下の動画のようになります。
プレースホルダーセレクタ
@extendディレクティブは、セレクタを継承することが出来るのでコンパイルされたCSSに継承元のセレクタも生成されます。
しかし、継承専用のセレクタとして扱いたいなど継承元のセレクタがコンパイル後に不要な場合は、プレースホルダーセレクタ(Placeholder selector)という専用のセレクタを使えば解決することが出来ます。
プレースホルダーセレクタは、以下のコードのようにid(#
)やクラス(.
)の代わりに%
をつけて定義します。
1
2
3
4
/* .sampleにプレースホルダーセレクタを使う場合 */
%sample {
color: red;
}
例えば、先ほどの.content1
に.base-content
を継承したコードをプレースホルダーセレクタに変更すると、以下のコードのようになります。
1
2
3
4
5
6
7
8
9
10
11
%base-content { /* .base-contentから%base-contentに変更 */
border: 1px solid grey;
font-size: 20px;
padding: 20px;
width: 200px;
}
.content1 {
@extend %base-content; /* ここも%base-contentに変更 */
border-color: red;
}
上記のコードがコンパイルされたCSSは、以下のように継承元のセレクタが生成されていない事が分かりますね。
@extendと@mixinの違いとは?
@extendディレクティブと似た機能には、@mixinディレクティブがありましたね。
2つの違いや使い分けは、以下の通りです。
- @extendディレクティブは、関連性のあるルール同士に使う
- @mixinディレクティブは、関連性のないルール同士に使える
- プロパティ値だけ変えてスタイルを使う場合は、@mixinディレクティブを使う
まずは、@extendディレクティブを見ましょう。
以下のコードの.base-button
は、全てのボタンのベースとなるスタイルを設定してます。.green-button
の場合はボタンと関連性があるので、.base-button
を@extendで継承する事が出来ます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* 全てのボタンのベースのスタイルを設定 */
.base-button {
border-style: solid;
display: inline-block;
}
/* buttonに関連性があるので、@extendで.base-buttonを継承出来る*/
.green-button {
@extend %base-button;
background: green;
}
/* .base-buttonのスタイルを使いたいが、関連性がないので@extendで継承しない!*/
.footer {
background: grey;
}
しかし、.footer
の場合はボタンと全く関連性がないので、.base-button
のスタイルを使いたくても@extendで継承することはありません。このように@extendディレクティブは、関連性のあるルール同士に使います。
次は、@mixinディレクティブを見ましょう。
以下のコードのように@mixinで定義するbase-font
は、フォントのベースとなるスタイルを設定しています。@mixinディレクティブは、@extendディレクティブと違ってフォントに関連性のない.nav
や.header
などに対してbase-font
を@includeして使う事が出来ます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* フォントのベースのスタイルを設定 */
@mixin base-font {
color: #575f74;
font-family: sans-serif;
}
.nav {
@include base-font;
}
.header {
@include base-font;
}
.footer {
@include base-font
}
このように@mixinディレクティブは、関連性のないルール同士に使う事が出来ます。
また、@mixinディレクティブは引数を渡す事も出来るので、以下のコードのようにプロパティ値だけ毎回変えて使いたい場合にも便利です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@mixin base-font($color) {
color: $color;
font-family: sans-serif;
}
.nav {
@include base-font(#575f74);
}
.sidber {
@include base-font(#4b505e);
}
.footer {
@include base-font(#474a52);
}
4. @importディレクティブ
@importディレクティブは、外部のスタイルシートである「.scssの拡張子のファイル」をインポートする機能です。指定したファイルは、CSSにコンパイルされると1つのファイルとして書き出されます。
1
2
3
4
5
/* ファイルをインポートする */
@import "ファイル名.scss";
/* 拡張子は省略可能なので、下記でも良い*/
@import "ファイル名";
下記の様に、カラーをまとめたファイルをインポートした時の例を見てみます。
1
2
3
/* 色をまとめたファイル */
$base-black: #383838;
$base-write: #fff;
1
2
3
4
5
6
7
/* 拡張子は省略可能 */
@import "color.scss";
/* color.scssで定義したカラーを利用する */
main {
color: $base-black;
}
上記のコードをCSSへコンパイルすると、下記の様になります。
1
2
3
main {
color: #383838;
}
変数でカラーコードを定義する事によって、使い回せるのはもちろんですが、1つ1つ何を意味しているのか分かりやすくなりコードの可読性も上がります。特にミックスインを外部ファイル化すると、必要な時に@importで呼び出す形にするとコードの保守性が上がり管理しやすくなります。
SCSS記法の応用的な使い方
この章では具体例を挙げて実際にどのような場面でSCSS記法が便利になるのかを説明していきます。
@mixinディレクティブ
@mixinディレクティブは、SCSS記法の様々な使い方のmixinディレクティブの章でスタイル定義を再利用するための仕組みと説明しました。
この章ではmixin関数を定義してスタイルを再利用できる様になることで、どのような場面で便利になるのか具体例を使って説明します。
例えば、信号がよく出現する道路交通ルールについて勉強できるサイトがあるとします。
以下の様に北交差点にある信号機のhtmlとscssがあります。
See the Pen mixin関数を定義する前 by miyajima yuya (@pikawaka) on CodePen.
このとき赤色だけopacity: 1;
のスタイルが定義されているので、今は決め打ちで赤色が点いている状態です。
これを決め打ちではなく、mixin関数を定義して関数の引数によって光る信号の色を決められると便利ではないでしょうか?
引数によって光る信号の色を変えるには、以下の2点を定義すると実現できます。
- 関数を呼んだ時に必ず読み込まれるスタイルの定義
- SCSS記法の条件分岐
関数を呼んだ時に必ず読み込まれるスタイルの定義
まずは既存のスタイルをmixin関数に置き換えます。
変更前は以下のファイルの内容でしたね。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.nourth-intersection {
.signal {
height: 100px;
width: 300px;
background-color: gray;
display: flex;
.signal-child {
width: 100px;
height: 100px;
border-radius: 50%;
opacity: 0.2;
}
.red-signal {
background-color: red;
opacity: 1; //赤色だけ追加
}
.yellow-signal {
background-color: yellow;
}
.blue-signal {
background-color: blue;
}
}
}
上記のコード↑を以下のコード↓に変更します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
@mixin current-signal($color) {
/* nourth-intersectionクラスは信号クラスを定義するクラスではないので
mixinには含めません。*/
.signal {
height: 100px;
width: 300px;
background-color: gray;
display: flex;
.signal-child {
width: 100px;
height: 100px;
border-radius: 50%;
opacity: 0.2;
}
.red-signal {
background-color: red;
}
.yellow-signal {
background-color: yellow;
}
.blue-signal {
background-color: blue;
}
}
//ここから追加
@if $color == red {
.red-signal {
opacity: 1 !important;
}
} @else if $color == yellow {
.yellow-signal {
opacity: 1 !important;
}
} @else if $color == blue {
.blue-signal {
opacity: 1 !important;
}
} @else {
.signal-child {
opacity: 1 !important;
}
}
}
// @mixinで定義したスタイルを@includeで呼び出す
.nourth-intersection {
@include current-signal(red);
}
変更後のscssファイルを見てみると@mixin current-signal($color) {~~~}
にはmixinの関数が定義されていて、.nourth-intersection {@include current-signal(red);}
では、mixinで定義したcurrent-signal(red)
をincludeしてスタイルを埋め込んでいます。
current-signal(red)
のスタイルの中身を確認します。
下記のコードのスタイルは、current-signal関数が呼ばれた時に必ず読み込まれるスタイルになります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.signal {
height: 100px;
width: 300px;
background-color: gray;
display: flex;
.signal-child {
width: 100px;
height: 100px;
border-radius: 50%;
opacity: 0.2;
}
.red-signal {
background-color: red;
}
.yellow-signal {
background-color: yellow;
}
.blue-signal {
background-color: blue;
}
}
このスタイルが読み込まれることによって信号の見た目のベースができます。
親の.nourth-intersectionにネストして上記のスタイルを定義することで、見た目のベースができていることを確認できます。
See the Pen mixinの説明の既存で必ず読み込まれるスタイル by miyajima yuya (@pikawaka) on CodePen.
current-signal関数はこの信号のベースのスタイルができた前提で、条件分岐を使ってどの信号を光らせるか指定できる関数になります。
SCSS記法の条件分岐
元々のscssファイルを見てみると、@if ~ @else
が追加されていることが分かります。このscssファイルの中のifは、rubyのifやその他の言語のifと使い方はほとんど同じです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@mixin current-signal($color) {
@if $color == red {
.red-signal {
opacity: 1 !important;
}
} @else if $color == yellow {
.yellow-signal {
opacity: 1 !important;
}
} @else if $color == blue {
.blue-signal {
opacity: 1 !important;
}
} @else {
.signal-child {
opacity: 1 !important;
}
}
}
.nourth-intersection {
@include current-signal(red);
}
current-signal(red)
は引数にredを渡しているので、@mixin current-signal($color)
で$colorはredを受け取ります。
つまり@if $color == red
では$colorはredなので、.red-signal {opacity: 1 !important;}
のスタイルが読み込まれます。それ以降の@else if
などは読み込まれません。
.nourth-intersection
のスタイルは以下の様なスタイルに置き換わったとイメージしてください。
1
2
3
4
5
6
7
8
9
10
11
12
// before
.nourth-intersection {
@include current-signal(red);は以下のスタイルに置き換わる
}
// after
.nourth-intersection {
// @include current-signal(red);は以下のスタイルに置き換わる
.red-signal {
opacity: 1 !important;
}
}
そしてコンパイル後のcssは下記の様になります。
1
2
3
.nourth-intersection .red-signal {
opacity: 1 !important;
}
では、@include current-signal(yellow)にした場合はどうなるか確認します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@mixin current-signal($color) {
@if $color == red {
.red-signal {
opacity: 1 !important;
}
} @else if $color == yellow {
.yellow-signal {
opacity: 1 !important;
}
} @else if $color == blue {
.blue-signal {
opacity: 1 !important;
}
} @else {
.signal-child {
opacity: 1 !important;
}
}
}
.nourth-intersection {
@include current-signal(yellow);
}
今回は@if $color == red
には当てはまらないので、skipされます。次の@else if $color == yellow
には条件が当てはまり、下記の様なcssにコンパイルされます。
1
2
3
.nourth-intersection .yellow-signal {
opacity: 1 !important;
}
次は、if、else ifの条件にない引数を指定した場合を見てみましょう。
1
2
3
.nourth-intersection {
@include current-signal(all);
}
どの条件も当てはまらないとなり@else {.signal-child {opacity: 1 !important;}
が読み込まれ、下記の様にcssがコンパイルされます。
1
2
3
.nourth-intersection .signal-child {
opacity: 1 !important;
}
続いて、引数を渡さない場合はどうなるかみてみましょう。
1
2
3
4
.nourth-intersection {
// Error: Missing argument $color.とエラーが出る
@include current-signal();
}
何も渡さなかった場合は、Error: Missing argument $color.
とエラーがでてCSSにコンパイルされません。
引数を渡さない場合は、デフォルト引数を使います。
@mixin current-signal($color)
となっている部分を@mixin current-signal($color: blue)
に修正します。
この様にデフォルト引数を指定すると、@include current-signal();としても$colorにはデフォルトでblueが入った状態で処理されます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// デフォルト引数にblueを指定
@mixin current-signal($color: blue) {
@if $color == red {
.red-signal {
opacity: 1 !important;
}
} @else if $color == yellow {
.yellow-signal {
opacity: 1 !important;
}
} @else if $color == blue {
.blue-signal {
opacity: 1 !important;
}
} @else {
.signal-child {
opacity: 1 !important;
}
}
}
.nourth-intersection {
@include current-signal();
}
上記↑のscssは下記↓のcssにコンパイルされます。
1
2
3
.nourth-intersection .blue-signal {
opacity: 1 !important;
}
基本的には青信号を付けることが多いので、引数を渡さない場合は青信号を点ける様にしたいという場合に便利ですね!
@mixin関数に引数と条件分岐を使った場合のまとめはこの様になります。
mixin関数を再利用して便利さを実感しよう
このcurrent-signal関数を再利用することでどう便利になるか見ていきましょう。
current-signal関数の中身が読める様になったので、まず一度全体を見直してみましょう。
全体はこの様になってました。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@mixin current-signal($color) {
.signal {
height: 100px;
width: 300px;
background-color: gray;
display: flex;
.signal-child {
width: 100px;
height: 100px;
border-radius: 50%;
opacity: 0.2;
}
.red-signal {
background-color: red;
}
.yellow-signal {
background-color: yellow;
}
.blue-signal {
background-color: blue;
}
}
@if $color == red {
.red-signal {
opacity: 1 !important;
}
} @else if $color == yellow {
.yellow-signal {
opacity: 1 !important;
}
} @else if $color == blue {
.blue-signal {
opacity: 1 !important;
}
} @else {
.signal-child {
opacity: 1 !important;
}
}
}
.nourth-intersection {
@include current-signal(red);
}
.nourth-intersection
のクラスに@include current-signal(red);
をつけているので、今は赤信号が点いている状態です。
See the Pen gOrVoeg by miyajima yuya (@pikawaka) on CodePen.
黄色と青色が半透明になっているのはopacity: 0.2を指定しているからになります。
1
2
3
4
5
6
.signal-child {
width: 100px;
height: 100px;
border-radius: 50%;
opacity: 0.2;
}
基本的には赤色と黄色と青色はopacity: 0.2を指定して半透明になっているのですが、@include current-signal(red);
を使って.red-signal {opacity: 1 !important;}
のスタイルを埋め込んでいるので、赤信号が付くことになります。
mixin関数に引数を渡して光る色を簡単に指定できます。
つまりmixin関数の良いところは
- スタイル定義を再利用できるところ
- 引数や条件分岐を使ってスタイルを柔軟に変えられるところ
ですから、使う回数が多ければ多いほどmixinは便利になります。
今は北交差点しかありませんが、東交差点、南交差点、西交差点を追加しましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<div class="nourth-intersection">
<p>北交差点</p>
<div class="signal">
<div class="signal-child red-signal"></div>
<div class="signal-child yellow-signal"></div>
<div class="signal-child blue-signal"></div>
</div>
</div>
<!--ここから追加-->
<div class="east-intersection">
<p>東交差点</p>
<div class="signal">
<div class="signal-child red-signal"></div>
<div class="signal-child yellow-signal"></div>
<div class="signal-child blue-signal"></div>
</div>
</div>
<div class="south-intersection">
<p>南交差点</p>
<div class="signal">
<div class="signal-child red-signal"></div>
<div class="signal-child yellow-signal"></div>
<div class="signal-child blue-signal"></div>
</div>
</div>
<div class="west-intersection">
<p>西交差点</p>
<div class="signal">
<div class="signal-child red-signal"></div>
<div class="signal-child yellow-signal"></div>
<div class="signal-child blue-signal"></div>
</div>
</div>
続いてscssファイルを修正します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
@mixin current-signal($color: blue) {
.signal {
height: 100px;
width: 300px;
background-color: gray;
display: flex;
.signal-child {
width: 100px;
height: 100px;
border-radius: 50%;
opacity: 0.2;
}
.red-signal {
background-color: red;
}
.yellow-signal {
background-color: yellow;
}
.blue-signal {
background-color: blue;
}
}
@if $color == red {
.red-signal {
opacity: 1 !important;
}
} @else if $color == yellow {
.yellow-signal {
opacity: 1 !important;
}
} @else if $color == blue {
.blue-signal {
opacity: 1 !important;
}
} @else {
.signal-child {
opacity: 1 !important;
}
}
}
.nourth-intersection {
@include current-signal(red);
}
// ここから追加
.east-intersection {
@include current-signal(yellow);
}
.south-intersection {
@include current-signal();
}
.west-intersection {
@include current-signal(all);
}
この様に変更すると、下記の様に表示されます。
See the Pen codepen_final by miyajima yuya (@pikawaka) on CodePen.
東交差点には yellow
、南交差点には引数を渡さずデフォルト引数のblue
、西交差点にはall
を渡してそれぞれ指定したい部分で色が点いていることが分かります。
これをもしmixinを使わなかった場合は、大袈裟に書くと下記の様に一つ一つ交差点のクラスを指定してスタイルも指定しなければなりません。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
.north-intersection {
.signal {
height: 100px;
width: 300px;
background-color: gray;
display: flex;
.signal-child {
width: 100px;
height: 100px;
border-radius: 50%;
opacity: 0.2;
}
.red-signal {
background-color: red;
opacity: 1;
}
.yellow-signal {
background-color: yellow;
}
.blue-signal {
background-color: blue;
}
}
}
.east-intersection {
.signal {
height: 100px;
width: 300px;
background-color: gray;
display: flex;
.signal-child {
width: 100px;
height: 100px;
border-radius: 50%;
opacity: 0.2;
}
.red-signal {
background-color: red;
}
.yellow-signal {
background-color: yellow;
opacity: 1;
}
.blue-signal {
background-color: blue;
}
}
}
.south-intersection {
.signal {
height: 100px;
width: 300px;
background-color: gray;
display: flex;
.signal-child {
width: 100px;
height: 100px;
border-radius: 50%;
opacity: 0.2;
}
.red-signal {
background-color: red;
}
.yellow-signal {
background-color: yellow;
}
.blue-signal {
background-color: blue;
opacity: 1;
}
}
}
.west-intersection {
.signal {
height: 100px;
width: 300px;
background-color: gray;
display: flex;
.signal-child {
width: 100px;
height: 100px;
border-radius: 50%;
opacity: 1;
}
.red-signal {
background-color: red;
}
.yellow-signal {
background-color: yellow;
}
.blue-signal {
background-color: blue;
}
}
}
この様にそれぞれの交差点に一つ一つスタイルを追加するのは大変で管理し辛いですね。しかしmixinを使うとこの様にすっきり書けるというわけです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.nourth-intersection {
@include current-signal(red);
}
.east-intersection {
@include current-signal(yellow);
}
.south-intersection {
@include current-signal(blue);
}
.west-intersection {
@include current-signal(all);
}
明らかにmixinの方が管理しやすく便利なのが分かりますね。よく使うスタイルがあればmixinを使う様にしましょう。
この記事のまとめ
- Sassとは、CSSのスタイルシート言語の機能を拡張した言語のこと
- 「SASS記法」と「SCSS記法」の2種類ある
- Sassを使うことで、保守性が高まり人為的なミスを減らすことが出来る