【Sass入門】SCSSの基本的な書き方をコード付きで解説!
この記事のレベル
- 初心者向け
- 3
- 難易度
- 4
ホームページ等の開発において多くの方々が使用しているCSS。
そのCSSの課題を解消するために開発された言語が、今回紹介させていただくSCSSです。
このSCSSはCSSには無かったとても便利な機能が様々あり、
これからCSSやSCSSを覚えようという方に向けて、
SCSSとはいったいどんなものなのか。どんな書き方をすれば良いのかなど、
SCSSの基本的な書き方や機能などをわかりやすく解説します。
SCSSの基本的な特徴
今回紹介するSCSSとは、SASSというスタイルシートの記述方法のひとつです。
Sassの記法には2種類存在し、もう一つの記法はSASSといいます。
なかなか混同してしまいがちですが、
Sassという言語のには、「SCSS」と「SASS」の2つの記述方法があると理解してもらえると分かりやすいです。
この記事を読んで頂いている皆様はスタイルシート(CSS)を学ばれていると思います。
中級者程になられると、CSSにいろいろな課題はありませんか?
その様々な課題を解決し、コード管理を容易にした記述方法がSCSSです。
この記事では、そんなSCSSについて解説します。
CSSで変数を利用できる
PHPやJavascriptなど、プログラミングをされる方には変数という言葉は馴染みがあると思います。
この変数とは、繰り返し使う文字色や背景色などのコードに名前をつけることで、
再び使う時には名前を書くだけで呼び出せる機能です。
例えば、WEBサイトの文字色が#111とします。
お客様から「文字の色をもっと薄くして欲しい」という要望が合った場合
CSSだと絶望的ですよね…
それをSCSSは一発で解決できます。
$main_txt_color : #111;
$main_txt_colorという変数に#111のカラーを割り当てておけば、
カラーコードを変更することで$main_txt_colorを割り当てた箇所の文字色が一括で変更できるイメージです。
ネスト構造を利用できる
Sassはネスト(入れ子)で記述するので、コード数を短くできる特徴があります。
それにより、1つの処理をまとめられるため、シンプルで分かりやすいというメリットがあります。
シンプルで分かりやすいということは、メンテナンス性も高いという事になりますね。
CSSの書き方
#sample h1 {
font-size: 2.8rem;
font-weight: 700;
color: $h1_color;
margin-bottom: 20px;
}
#sample a {
@include hover_opacity;
color: #999;
flex-wrap: nowrap;
}
#sample a svg {
width: 1.4rem;
height: 1.4rem;
margin-right: 3px;
}
@media (max-width: 992px) {
#sample h1 {
font-size: 2.6rem;
line-height: 1.2;
}
}
SCSSの書き方
#sample {
h1 {
font-size: 2.8rem;
font-weight: 700;
color: $h1_color;
margin-bottom: 20px;
@media (max-width: 992px) {
font-size: 2.6rem;
line-height: 1.2;
}
}
a {
@include hover_opacity;
color: #999;
flex-wrap: nowrap;
svg {
width: 1.4rem;
height: 1.4rem;
margin-right: 3px;
}
}
}
スタイルシートを分けられる
SCSSは、スタイルシートを分けて管理できます。
例えば、共通パーツ用のSCSSファイル、ページコンテンツ部のSCSSファイル、コンポーネント部品用のSCSSファイルと
分けて管理することで、目的のファイルを見つけやすくなります。
SCSS
│-common
│-components
│-global
│-ja
│-page
│-style.scss
commonには、サイトのheaderやfooterやcontainerなどを管理。
componentsには、共通部品関連を管理。
globalには、フォント設定や、色管理、変数管理など、
階層名はなんでも良いですが、分かりやすい名前でSCSSファイルを管理できます。
条件分岐を利用できる
SCSSの条件分岐を活用すれば、CSSだけでは実現できなかった様々な処理が実装できます。
ひと昔は、PHPやjavascriptなどと連携させて処理する必要があったコードもSCSSファイルだけで完結します。
if 条件A {
スタイルA
}
@else if 条件B {
スタイルB
}
@else {
スタイルC
}
上記のコード例は、条件Aが成立した場合は、スタイルAが反映されます。
また、条件Aが成立しなかった場合は条件Bの真偽を判定して、条件Bが成立すればスタイルBが、成立しなければスタイルCが反映されるコードです。
実際の利用例としては下記のようになります。
$category: blog;
@if $category == blog {
.btn1 {
width: 200px;
}
}
@else {
.btn1 {
width: 100%;
}
}
変数に定義した条件を満たしている場合、上記の例であれば$category: blog;が変数に定義されているのでVScodeなどでSCSSをコンパイルした際、上記条件で.btn1の幅は200pxになります。
mixin機能を利用できる
mixin(ミックスイン)とは、予め定義したコードのまとまりを他の場所から呼び出せる機能です。
mixinに利用頻度の高いスタイルを定義しておくことで他の場所でも同じく使えるようになります。
何度も同じスタイルを記述する必要がなくなるため、作業効率アップや、メンテナンス性アップというメリットがあります。
mixin.scss
buttonリセット
@mixin button_reset {
background-color: transparent;
border: none;
cursor: pointer;
outline: none;
padding: 0;
appearance: none;
}
style.scss
button {
@include button_reset;
・・・
}
上記はbuttonに対する定義の例です。
予めmixin.scssで『@mixin button_reset』を定義しておきます。
style.scssでbuttonに対して『@include button_reset;』と記述するだけで、ボタンのリセットCSSがあたります。
実践を見据えたSCSSの書き方
ここではSCSS実践を見据えたSCSSの書き方ついて例を交えて解説します。
変数
変数とは、くり返し使用したい値などを変数として管理できる機能です。
CSSにも変数はありますが、変数に対応していないブラウザも存在するため、変数を使いたい場合はSCSSがおすすめです。
記述方法
$変数名: 値;
具体例
#{$posLeft}とする事で、変数を文字列としても扱えます。
$black: #111;
$posLeft: left;
.text {
color: $black;
}
.card {
background: $black;
margin-#{$posLeft}: 30px;
}
出力結果
.text {
color: #111;
}
.card {
background: #111;
margin-left: 30px;
}
ネスト(入れ子)
記述方法
.hoge1 {
プロパティ: 値;
.hoge2 {
プロパティ: 値;
.hoge3 {
プロパティ: 値;
}
}
}
具体例
.item1 {
width: 200px;
.item2 {
width: 100px;
.item3 {
width: 50px;
}
}
}
出力結果
.item1 {
width: 200px;
}
.item1 .item2 {
width: 100px;
}
.item1 .item2 .item3 {
width: 50px;
}
条件分岐
とは、指定した条件が満たされている場合、満たされていない場合で結果を変化させる考え方です。
Sassは、PHPなど他のプログラミング言語で頻繁に出てくる条件分岐や、くり返しなどを制御できます。
この条件分岐(if文)は指定した条件に一致した場合のみ処理を実行します。
以下のように記述することで、条件によってスタイルを変更できます。
条件を1つのみで指定する場合
@if 条件 {
// 条件が合致したらこの中の処理を実行する。
} @else {
// 条件が合致しない場合はこの中の処理を実行する。
}
条件を複数指定する場合
@if 条件1 {
// 条件1が合致したらこの中の処理を実行する。
} @else if 条件2 {
// 条件2が合致したらこの中の処理を実行する。
} @else {
// どの条件も合致しない場合はこの中の処理を実行する。
}
具体例
$position: left;
$width: 100%;
// 条件を1つのみで指定する場合
.sample1 {
@if $position == left {
padding-left: 10px;
} @else{
padding-right: 10px;
}
}
// 条件を複数指定する場合
.sample2 {
@if $width > 300px {
margin-right: 10px;
} @else if $width < 200px {
margin-left: 10px;
} @else {
margin-top: 10px;
}
}
出力結果
.sample1 {
padding-left: 10px;
}
.sample2 {
margin-right: 10px;
}
また、条件式として使用可能な比較演算子は、以下のようなものがあります。
比較演算子 | 解説 |
---|---|
A==B | AとBは等しい |
A>B | AはBより大きい |
A<B | AはBより小さい |
A>=B | AはB以上 |
A<=B | AはB以下 |
A!=B | AとBは等しくない |
論理演算子については、Sassでは「&&」「||」を使用できませんが、代わりに以下のものが使用できます。
論理演算子 | 解説 |
---|---|
and | かつ |
or | または |
not | AはBより小さい |
A>=B | 否定 |
$value: 50;
@if $value > 10 and $value < 100 {
$valueが10よりも大きくてかつ100よりも小さい場合スタイルを反映
}
このように、比較演算子と論理演算子を組み合わせると、複雑な条件設定ができるようになります。
反復処理
反復処理とは、指定した手順をくり返し処理する機能です。
無限にくり返すことも、ある条件になるまでくり返すことも、記述次第で実装が可能です。
@for
for文は、設定した開始値から終了値までの処理をくり返し実行します。
through文は、終了値を含め処理を実行するのに対し、toは終了値は含みません。
記述方法
@for $変数 from 開始値 to 終了値 {
//変数が開始値から終了値未満の間、この中の処理を実行。
}
具体例
@for $i from 1 through 3 {
.sampleA-#{$i} {
margin-right: 10px * $i;
}
}
@for $i from 1 to 3 {
.sampleB#{$i + 5} {
width: (50px * $i) + 10px;
}
}
出力結果
//throughなので3回くり返す
.sampleA-1 {
margin-right: 10px; // 10px × 1
}
.sampleA-2 {
margin-right: 20px; // 10px × 2
}
.sampleA-3 {
margin-right: 30px; // 10px × 3
}
//toなので、3回目は含まれない
.sampleB-1 {
width: 60px; // ( 50px × 1) + 10px
}
.sampleB-2 {
width: 110px; // ( 50px × 2) + 10px
}
@while
while文は、指定した条件に合う場合無限にくり返し処理を実行します。
記述方法
@while 条件 {
// 条件が合致している間、この中の処理を繰り返し実行する。
}
具体例
$i: 1;
@while $i < 4 {
.sample-#{$i} {
width: 50px * $i;
}
$i: $i + 1;
}
出力結果
.sample-1 {
height: 50px; // 50px × 1
}
.sample-2 {
height: 100px; // 50px × 2
}
.sample-3 {
height: 150px; // 50px × 3
}
@each
主に配列にキーと値がセットで格納されている場合に用いります。
$変数名 : {
キー:値,
キー:値
}
@each $key, $value in 変数名 {
.#{$key} {
プロパティ:値;
}
}
@forと@whileと@eachの用途の違い
上記でも解説しましたが、@for と @whileと @each の用途の違いのおさらい。
@whileは、与えられた条件を満たしている場合に処理を繰り返します。
繰り返し処理には @forも用いられますが、@forは繰り返しの回数が決まっている場合に、一方 @while は繰り返しの回数が決まっておらず、条件を満たしている限り処理を繰り返したい場合によく用いられます。
@eachは、配列にキーと値をセット(連想配列)で格納する場合に用いります。
簡単に言うと、回数を指定する場合は @for で、特定の条件を用いる場合は @while 。
配列が連想配列の場合は @each と覚えると良いでしょう。
mixin
mixinとは、コードのまとまりを他の場所から呼び出せる機能です。
@includeを使って呼び出すことができ、繰り返し使う事ができます。
mixin.scssなどでルールセットとして1ファイルで一括管理する事ができます。
また、mixinには引数(仮引数と実引数)を指定する事ができます。
※引数:パラメータとも言います。
※実引数:実際にmixinに与えられる引数のこと。
※仮引数:実際に引数が与えられるまで定まらない仮の引数のこと。初期値という言い方が一般的。
@contentを使用する場合はちょっと特殊です。
@mixin の中で @content; と記述するとコンテントブロックを渡すことができます。
これにより1つの mixin で呼び出し側に合わせた処理が可能になります。
引数を指定しない場合の記述方法
@mixin mixin名 {
プロパティ: 値;
}
.sampleA {
@include mixin名;
}
引数を指定しない場合の具体例
@mixin txt1 {
color: #cc0;
font-size: 18px;
font-weight: 700;
}
.sampleA{
@include txt1;
}
引数を指定しない場合の出力結果
.sampleA{
color: #cc0;
font-size: 18px;
font-weight: 700;
}
引数を指定する場合の記述方法(初期値なし)
mixin mixin名($引数名1, $引数名2) {
プロパティ: $引数名1;
プロパティ: $引数名2;
}
.sampleB {
@include mixin名(引数1, 引数2);
}
引数を指定する場合の具体例(初期値なし)
@mixin txt2($color,$size, $weight) {
color: $color;
font-size: $size;
font-weight: $weight;
}
.sampleB{
@include txt2(#c00, 18px, 700);
}
引数を指定する場合の出力結果(初期値なし)
.sampleB{
color: #c00;
font-size: 18px;
font-weight: 700;
}
引数を指定する場合の記述方法(初期値あり)
@mixin mixin名($引数名1: 初期値, $引数名2: 初期値) {
プロパティ: $引数名1;
プロパティ: $引数名2;
}
.sampleC {
@include mixin名();
// ここで引数を設定しない場合は初期値に設定した値が適用されます。
}
引数を指定する場合の具体例(初期値あり)
@mixin txt3($color : #c00, $size: 18px, $weight: 700) {
color: $color;
font-size: $size;
font-weight: $weight;
}
.sampleC{
@include txt2('', 18px, 700);
}
引数を指定する場合の出力結果(初期値あり)
.sampleC{
color: #c00;//指定しなかったので、初期値の#c00が代入されます
font-size: 18px;
font-weight: 700;
}
@contentを使用する場合の記述方法
@mixin mixin名 {
@content;
}
.hoge {
@include mixin名 {
// ここに記述した内容は@contentの部分に記載されていることになります。
}
}
@contentを使用する場合の具体例
@mixin sp {
@media screen and (max-width: 767px) {
@content;
}
}
p {
font-size: 16px;
// スマホのCSSプロパティをmediaクエリのコンテンツブロックへ渡す。
@include sp {
font-size: 14px;
}
}
@contentを使用する場合の出力結果
p{
font-size:16px;
}
@media screen and (max-width: 767px) {
p{
font-size:14px;
}
}
配列
配列とは、1つの配列名に対して複数の値を格納できるオブジェクトを定義できます。
例とて、箱を5個積み上げて1個めには衣類。2個目にはタオル。3個目には靴下といった形でデータを収納するイメージです。
配列にはカンマ区切りの配列と、マップ型(連想配列)の2種類があります。
用途に合わせて選択します。
変数itemsにカンマ区切りで複数指定の場合の記述方法
$items: itemA, itemB, itemC, itemD;
@each $value in 変数名 {
.#{$value}class名 {
プロパティ: 値(計算値);
}
}
変数itemsにカンマ区切りで複数指定の場合の具体例
$items: red, white, gray;
@each $value in $items {
.#{$value}-bg {
background-color: #{$value};
}
}
変数itemsにカンマ区切りで複数指定の場合の出力結果
.red-bg {
background-color: red;
}
.white-bg {
background-color: white;
}
.gray-bg {
background-color: gray;
}
マップ型(連想配列)の場合の記述方法
$変数名:(
key : 値,
key : 値,
key : 値
);
@each $key, $value in 変数名 {
.#{$key}class名 {
プロパティ: 値(計算値);
}
}
マップ型(連想配列)の場合の具体例
$bg-color:(
red : #c00,
white : #fff,
gray : #808080
);
@each $key, $value in 変数名 {
.bg-#{$key} {
background-color: #{$value};
}
}
マップ型(連想配列)の場合の出力結果
.bg-red {
background-color: #c00;
}
.bg-white {
background-color: #fff;
}
.bg-gray {
background-color: #808080;
}
関数
関数とは、CSSのプロパティの値を自動的に計算させる機能のようなものです。
関数の宣言 記述例
@function rem(引数) {
@return 計算式;
}
関数の宣言 具体例
@function rem($px) {
@return $px / 16 * 1rem;
}
p {
font-size: rem(20);
}
関数の宣言 出力結果
p {
font-size: 1.25rem;
}
モジュール
SCSSは、分割したファイルをモジュールとしてインポートして、1つのCSSファイルにまとめて出力することができます。
例えば、以下のディレクトリ構造でモジュール化する場合を解説します。
SCSS
│-_bace.scss
│-_components.scss
│-style.scss
記述方法
bace.scss
html {
color: #111;
background: #f1f1f1;
font-size: 14px;
line-height: 1.6;
}
body {
background: #fff;
margin: 0;
}
components.scss
#header {
width: 100%;
height: 50px;
display: flex;
justify-content: flex-start;
align-items: center;
}
#footer{
background-color: #111;
display: flex;
justify-content: center;
align-items: center;
}
style.scss
@use '_bace';
@use '_components';
出力結果
html {
color: #111;
background: #f1f1f1;
font-size: 14px;
line-height: 1.6;
}
body {
background: #fff;
margin: 0;
}
#header {
width: 100%;
height: 50px;
display: flex;
justify-content: flex-start;
align-items: center;
}
#footer{
background-color: #111;
display: flex;
justify-content: center;
align-items: center;
}
まとめ
SCSSでは、解説した通りCSSでは出来なかった様々な便利な機能があります。
SCSSでこんな事ができたっけ?程度で構いませんので、覚えておいて損は無いです。
CSSで手間のかかっていた記述や、JavascriptやPHPなどと連携して書いていた記述がSCSSだけで完結する事や、変数やネスト構造を利用することで、効率的に記述できるようになります。
SCSSを活用して、開発期間の短縮化やメンテナンス性の向上を実現しましょう。
以上で解説を終わります。