SCSSでCSSをもっと書きやすく!
SCSS(Sassy CSS)は、Sass(Syntactically Awesome Stylesheets) の一種で、CSS(Cascading Style Sheets)をより効率的に書くための拡張言語です。CSSの書き方に柔軟性と機能を追加することで、スタイルの記述をシンプルかつ再利用可能にすることを目的としています。
「Live Sass Compiler」が便利
SCSSは、拡張子が.scssとなります。しかし、.cssファイルでないとブラウザで扱えません。
ですので、scss→cssでファイルを変換(コンパイル)しないといけません。
そこで便利なのが、VSCodeの拡張機能「Live Sass Compiler」になります。
拡張機能をインストールすると、VSCodeの右下のツールバーに「Watch Sass」のボタンが出るので、押すとファイルを監視してくれ、保存時に自動でCSSファイルにコンパイルしてくれます。
VSCodeでcssファイルのコンパイル先を指定できます。
"liveSassCompile.settings.formats": [
{
"format": "compressed", // コンパイル時のフォーマットを圧縮に設定
"savePath": "~/../css", // 保存パスを設定
// "savePath": "", 保存パスの設定(scssと同じフォルダ)
"extensionName": ".css" 拡張子を.cssに設定
}
],
"liveSassCompile.settings.excludeList": [
"/**/node_modules/**", // 除外リストにnode_modulesを追加
"/.vscode/**" // 除外リストに.vscodeを追加
],
"liveSassCompile.settings.generateMap": true, // ソースマップの生成を無効化
※savePathを""のように空にしたら、同じ階層にcssがコンパイルされます。
※JSONデータなので、最後の行に追加する場合は、末尾の,(カンマ)は不要です。逆に他の設定があれば、そちらに,(カンマ)が必要です。
ここから、SCSSの便利な機能を紹介します。
まずは簡単なものから徐々に慣れていきましょう!
ネストで書くことが出来る
入れ子(ネスト)で書くことができるので、BEMなどでClass名を付けていると相性が良いです。
■CSSの場合
.about{
width: 300px;
}
.about__text{
color: #ffffff:
}
■SCSSの場合
.about{
width: 300px;
&__text{
color: #ffffff:
}
}
&で親の.aboutになります。
変数が使える
SCSSでは、変数を使って値(色、フォントサイズ、マージンなど)を定義することができます。これにより、スタイルの一貫性を保つことが容易になり、コードのメンテナンスも簡単になります。
$primary-color: #333;
body {
color: $primary-color;
}
ミックスイン(Mixin)
再利用可能なコードブロックを作成するための機能があります。
(例)よく使うボタンを定義して、色などを変更可能にしておく。
// ボタンのベーススタイル
@mixin button($bg-color, $text-color, $padding: 10px 20px) {
background-color: $bg-color;
color: $text-color;
padding: $padding;
border: none;
border-radius: 5px;
cursor: pointer;
text-transform: uppercase;
transition: background-color 0.3s;
&:hover {
background-color: darken($bg-color, 10%);
}
}
// ボタンの適用例
.primary-btn {
@include button(#3498db, #fff);
}
.secondary-btn {
@include button(#2ecc71, #fff, 8px 16px);
}
(例)レスポンシブのMixinの例
// ブレイクポイントの定義
$breakpoints: (
small: 576px,
medium: 768px,
large: 992px,
xlarge: 1200px
);
// レスポンシブ用のミックスイン
@mixin respond-to($size) {
@if map-has-key($breakpoints, $size) {
@media (max-width: map-get($breakpoints, $size)) {
@content;
}
}
}
// レスポンシブデザインの適用例
.container {
width: 100%;
padding: 20px;
@include respond-to(small) {
padding: 10px;
}
@include respond-to(medium) {
padding: 15px;
}
@include respond-to(large) {
padding: 20px;
}
}
ファイルを分けることができる
サイト構築時はファイルを分けて、最終的には同じstyle.cssにまとめる、などができます。
(例)style.scss
// 変数や共通スタイル
@use 'varible';
@use 'breakpoints';
@use 'common';
// ヘッダーとフッター
@use 'header';
@use 'footer';
// コンテンツ別のスタイル
@use 'about';
@use 'vision';
@use 'news';
@use 'product';
ファイル構成
./scss ├── _varible.scss ├── _breakpoints.scss ├── _common.scss ├── _footer.scss ├── _header.scss ├── _about.scss ├── _vision.scss ├── _news.scss ├── _product.scss └── style.scss
使うとき
// _variables.scss
$primary-color: #3498db;
// style.scss
@use 'variables';
body {
color: variables.$primary-color;
}
モジュール化して管理する方法を紹介
例えば、以下のようにモジュールに分けると管理しやすいですね。
scss
├── component
│ ├── _btn.scss
│ ├── _container.scss
│ ├── _fade-in.scss
│ ├── _index.scss
├── foundation
│ ├── _basic.scss
│ ├── _index.scss
│ └── _reset.scss
├── global
│ ├── _index.scss
│ ├── _mixin.scss
│ └── _var.scss
├── layout
│ ├── _about.scss
│ ├── _access.scss
│ ├── _archive.scss
│ ├── _contact.scss
│ ├── _footer.scss
│ ├── _fv.scss
│ ├── _header.scss
│ ├── _index.scss
│ ├── _single.scss
│ └── _top-news.scss
└── style.scss
style.scss
@charset "UTF-8";
@use "foundation";
@use "component";
@use "layout";
上記のように@useを使うことで、各 _index.scss ファイルを読み込むことで、コンポーネントやレイアウトなど、各セクションのスタイルを一括で利用できます。
style.scss → foundation(_index.scss) のようにファイルを読み込んでますね。
でも、@useだと、style.scss → global(_index.scss) → _var.scssのように、2段階ファイルを潜るときにはエラーが出てしまいます。
これは、Sassのモジュールシステムにおけるカプセル化が原因です。
これは、@use がもたらす 名前空間の導入 と スコープの制限 によって起こります。
@use を使うと、そのモジュール(SCSSファイル)の中で定義された変数やmixin、関数は自動的に 名前空間でカプセル化 されます。
つまり、他のモジュールからそれらにアクセスする場合は、必ず名前空間(ファイル名など)を使って参照しなければなりません。
// _header.scss
@use 'variables';
.header {
color: variables.$primary-color; // 名前空間を使ってアクセス
}
名前空間を無効化するなら、下記のように書けます。
// _variables.scss
$primary-color: blue;
// _header.scss
@use 'variables' as *; // 名前空間を無効化
.header {
color: $primary-color; // 直接アクセス可能
}
2段階以上潜りたい場合はどうするのでしょうか?
そこで、@forwardがあります。
global/_index.scss
@forward "var";
@forward "mixin";
上記のように、@forwardを使うことで、モジュールを 転送(フォワード)し、呼び出したさらに上位のモジュールへ再公開することができます。
1段階潜るなら@useを使って、2段階以上潜るなら@forwardを使いましょう。