Sassを使う全人類に伝えたいこと
普段の業務でSassを使っている方には一度は読んでほしい記事です。
本記事で出てくるコードは全てSASSで書いていますが、SCSSでも全く同じ考え方をして大丈夫です。
Sassは「必ず使うべき」というわけではない
Sassはとても便利なツールです。普段から使っている人間からしたら、造作も無く効率よくコーディングを行えます。
しかし、プロジェクトに関わるメンバーによっては、Sassを扱えない方もいます。特にディレクターは扱えないケースが多いです(業務内容がそもそも違うので扱えないことに罪は1ミリもありません)。
そして、Sassを扱えないメンバーがサイト運用時に、コンパイルされたCSSを直接編集することはよくあります。そうした場合、コードのディレクトリには、「直接修正したCSS」と「修正が反映されていないSass」が混在しています。その状態でSassを編集したら、直接修正したCSSが上書きされてしまいます。
このようなことはよく起こりうるので、Sassを導入するかどうかは、プロジェクトに関わるメンバーや規模によって判断するようにしましょう。
ファイル全てにコメントアウトで「役割」を書く
Sassを使ううえで、個人的に一番重要な点です。
Sassは様々なスタイルをファイルを分割してコーディングを行いますが、そのファイルひとつひとつに、どのような役割なのかを一行目にコメントアウトするようにしています。
以下はボタンのスタイルを定義しているbutton.sassのファイルとします。一行目にファイルの役割を記述します。
// ボタンのコンポーネント
.c-button
font-size: 15px
font-weight: bold
大規模なコーディングになればなるほど、似たようなファイル名や役割のものが増え、どんどん訳がわからなくなります。なので、ファイルの役割をコメントアウトで必ず残すようにしましょう(開発中は仕様を覚えていても、時間が経つと忘れるものです)。
Sassに限らずですが、コメントアウトはとても大事です。
「変数」を効率良く使う
変数専用のファイルを作って、そこにはサイト内で使う共通の数値やコードを定義しています。
私は最低限、以下3つはどんなプロジェクトでも定義しています。
- ブレイクポイント
- 画像ディレクトリのパス(background-imageで使う用)
- 色(プライマリーカラーなど)
// ブレイクポイント
$breackpoint_sm: 640px
$breackpoint_md: 768px
$breackpoint_lg: 1024px
$breackpoint_xl: 1280px
// 画像パス
$path_img: "../img/"
// 色
$c--black: #333
$c--white: #fff
$c--primary: #4484f3
$c--accent: #df6a6a
mixinを効率良く使う
mixinを使うことで、効率よくコーディングができます。
以下の記事では、私が普段から使っているmixinをいくつか紹介しています。
なんでもかんでもmixinにするのはよくない
なんでもかんでもmixinにすると、逆に作業効率が悪くなったり保守性に欠けるコードになるので、しっかりと考えたうえで使うようにしましょう。
また、引数を使うことで柔軟なmixinを作れますが、使いすぎもよくありません。自分以外の人が理解できなくなってしまいます。2〜3個までが上限かなと個人的には思っています。
@extendは使う?使わない?
@extendは使う派と使わない派に分かれると思います。私は一部でのみ使う派です。
使わない派でよく聞く意見は、「コンパイルされたCSSが汚い」というものです。確かに、@extendを使うとスタイルがひとつにまとめられるので、結果的にCSSが読みにくくなってしまいます。
私は、BEMのmodifireを書く時のみ、@extendを使います。
@extendを使ったBEMのmodifireの書き方
BEMの基礎知識は省略します。気になる方はこちらをご覧ください。
@extendを使った場合、使わなかった場合のサンプルコードを用意しました。
@extendを使わない場合
<div class="text"></div>
<div class="text text--red"></div>
.text
font-size: 10px
&--red
color: red
@extendを使う場合
<div class="text"></div>
<div class="text--red"></div>
.text
$parent: &
font-size: 10px
&--red
@extend #{$parent}
color: red
@extendを使わない場合、<div class="text text--red">でtextとtext--redの2つのクラス名を書いていたのを、@extendを使うとtext--redだけでいいのでクラス名が短くなります。
&(アンパサンド)は使う?使わない?
こちらも派閥が存在して、Twitterでよく議論になる問題です。ちなみに私はゴリゴリ使っています。
&(アンパサンド)を使うのは良くない派でよく見かける主張は、「クラス名を検索したい時に引っかからない」というものです。
例えば、.parent__elmというクラスのスタイルを検索するためにparent__elmをコピーして検索した時に、以下のように&でスタイルを書いていたら検索には引っかかりません。
.parent
&__elm
color: #f00
言いたいことは分かります。確かに検索に引っかからないですね。
しかし、私の場合、parent__elmのかたまりで検索をしようと思ったことがありません。
普段は「BEM+FLOCSS」を使っているので、ファイルはコンポーネントごとに分けています。もし、parent__elmのスタイルを探すとしたら、parentでファイルを作っているので、そのファイルを開いて__elmで検索をかけます(そもそも1ファイルのコード量は少ないので検索することはほとんどありません)。
結論、私は少なくとも&を使うことによる弊害は全く感じないので、これからも使い続けます。
人によってはそれが不便と思う方もいるかもしれません。そういう方は&を使わなければいいと思います。なので、自分が使いやすい方法を選ぶのが一番です。
疑似要素の:hoverは@at-rootで書くと見やすくなる
<a>をホバーした時に、その疑似要素のスタイルを変えたい時はどのように書いていますか?Sassの機能をなにも使わないで書くと、以下のようになると思います。
a
color: #fff
background-color: #333
padding: 1em
&::before
content: ""
display: block
background-color: #f00
transition: background-color .2s
&:hover::before
background-color: #00f
&::beforeと&:hover::beforeが同階層のネストにいますね。これでも見にくいというわけではありませんが、&::beforeの中のネスト内に&:hover::beforeがあるとより見やすくなりませんか?以下のようなイメージです。
&::before
// スタイル
&:hover::before
// ホバースタイル
しかし、上記のように書くと.a::before:hover::beforeのようにコンパイルされてしまいます。入れ子にしているので当然です。
そこで@at-rootを使えばa:hover::beforeのように理想通りの形でコンパイルすることができます。
@at-rootの使い方
まずは結論です。このように書くと、理想通りの形になります。
// スタイルは省略
a
$parent: &
&::before
// beforeのスタイル
@at-root #{$parent}:hover::before
// beforeのホバー時のスタイル
$parentには&が値になっているので、aが値として定義されています。なので、@at-root #{$parent}:hover::beforeは@at-root a:hover::beforeと同義です。変数を使わないで@at-root a:hover::beforeのように書いてもいいですが、aのタグやクラス名が変わった時に、こちらも変えなければいけません。ミス防止の観点から変数化しています。
セレクタ内で変数を使う時は、#{$変数名}のように書きます。
@at-rootを使うと、その時点での入れ子のセレクタが全てリセットされます。例を用意しました。
// Sass
.parent
.child
order: 1
@at-root .child
order: 2
// コンパイル後のCSS
.parent .child { order: 1 }
.child { order: 2 }
このように、order: 2のセレクタには、.parentが含まれなくなります。
node-sassからDartSassへ移行
node-sassをまだ使っている方はDartSassへ移行しましょう。node-sassは非推奨です。
node-sassとDartSassの大きな違いは、@importの代わりに@useか@forwardを使う点です。ファイルや変数などに名前空間という概念が新たに加わったので、これまでと書き方が少しだけ変わります。