やっていかないとね。
環境
エディタはVisualStudio Code。
これに拡張機能「Live Sass Compiler」を入れる。
拡張機能により、SCSSを作成し、.scssを編集して保存すると.css.map、.cssが同ディレクトリに自動的に生成される。いちいち手動でコンパイルしなくていいので楽。内容によるかもだけど処理は軽い。
逆に言うと保存のたびにファイルが生成されるんで、不要なものは手作業で削除する必要がある。
全部キレイにインデントされるのは嬉しいし最上位のタグ毎に改行を一つ挟むので見やすいのだけど、cssの行数がめっちゃ延びる。なので最後にMinify処理(圧縮・軽量化)もしたいですね。拡張機能にあるので導入するといいです。楽。
scssとsassがあるけど、scssが主流らしいから自分もこれでやっていくことにする。
あと、sassは簡略化しまくりで事故るのが怖すぎる。
基本形
階層とか
body{
&.toppage{ /* body.toppage */
&.hoge{} /* body.toppage.hoge */
&--hoge{} /* body.toppage--hoge */
.hoge{} /* body.toppage .hoge */
}
&:before{} /* body:before */
header{ /* body header */
> nav{} /* body header > nav */
+ main{} /* body header + main */
}
}
階層を深めることで、classをつけたりclass末尾を追記したり子要素を入れたりできる。疑似要素も大丈夫。
階層を作る場合、階層だけが目的でstyleが含まれないものはコンパイル時にスルーされる。
つまり、これが
.hoge{
color: red;
.hoge{
.hoge{
color: red;
}
}
}
こうなる。
.hoge{
color: red;
}
.hoge .hoge .hoge{
color: red;
}
@importの代わりに@use
scssでもcssみたいに他のファイルを読み込める。
こういうのがあって
css
├ style.scss
├ target.scss
└ functions
├ mixin.scss
└ _mixin2.scss
style.scssに他のscssを持っていきたい場合。
@use "./target.scss";
@use "./target"; /* 拡張子を省略できる */
@use "./target.css"; /* cssも引っ張れる */
@use "./functions/mixin"; /* 別ディレクトリもOK */
@use "./functions/mixin2"; /* ファイル名前の「_」は省略して書く */
なんで@importじゃないのかというのはscss側の仕様。非推奨らしい。一応それぞれ役割が違うのでそれを理解した方がいい。
@importで書いたものは@importのままcssに記載される。
@useで書いたものは指定したファイルの中身がcssに展開される。
@useのほうが1つのファイルにまとまるので、ブラウザ読み込みの時に読み込みファイル数が減って都合がいいですね。
SCSSの変数
こうすると
$gray: #999;
body{
color: $gray;
}
こうなる
body{
color: #999;
}
cssにも:rootがあって変数が作れるけど、こっちはコンパイル時に展開されるという違いがある。
scss上で:rootを扱うこともできる。使い分けですね。
関数(@mixin)を使う
SCSSでは@mixinで関数を作って@includeで出力できる。
@mixin hogehoge(){
@content;
font-size: 20px;
}
.sample{
@include hogehoge();
color: red;
}
.sample{
color: red;
font-size: 20px;
}
「@content;」で既存のstyleを引っ張れる。
別ファイルに逃がす場合
関数を別ファイルにしたいときは@includeの書き方が変わる。
@use "./mixin"; //mixin.scssに関数を入れてるとする
.sample{
@include mixin.hogehoge(); //関数名の前にファイル名を記載する
color: red;
}
「どこにあるどの関数を使う」って形が基本と覚えたらいい。同ファイル内に関数が書かれてる場合は「どこに」を省略できるって感じに。
Media Query
関数で柔軟になったおかげでいろんな書き方で@mediaをやっていける。使い勝手の良さやらを求めた有志がいろんなのを書いてる。
個人的に気に入ったのはこれ。
以上、以下、以上~以下の3パターンが使える。数値は予め変数にまとめてあるのが地味にいいですね。各々のパターンがあるだろうからそれに合わせて調整する。ついでに.98px派だとmax-widthをいじることも必要。
記述的としてはcssと同様に該当の@mediaで括った中に書いたり、要素内に書いたりできる。
@include mq(min, md) {
.hoge{
font-size: 18px;
color: red;
}
}
.hogehoge{
color: red;
@include mq(min, sm) {
color: blue;
}
}
引数で割り振れるのは便利ですね。@mediaで囲わなくて良くなったので、要素毎に完結した書き方ができるようになった。囲ってる方が取りこぼしが防げて楽なんだけど、慣れの範疇かも。
で、まあ、要するに関数を作ったからcssより使い勝手がいいよってことで、普通に@mediaをベタ書きしても問題ない。
:hoverに関しては関数がありがたいかも。
@media (pointer: fine){}
例えばこう。
@mixin pf() {
@media (pointer: fine){
@content;
}
}
.hogehoge{
&:hover{
@include pf() {
color: blue;
}
}
}
@media (pointer: fine) {
.hogehoge:hover {
color: blue;
}
}
上記のなんやかんやをすべて混ぜるとこんな感じ。
$breakpoints: (
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px,
) !default;
@mixin mq($type, $bp1, $bp2:0) {
@if ($type == min) {
@media screen and (min-width: #{map-get($breakpoints, $bp1)}) {
@content;
}
} @else if ($type == max) {
$width: map-get($breakpoints, $bp1);
$width: $width - 0.02px;
@media screen and (max-width: #{$width}) {
@content;
}
} @else if ($type == bw) { // bw → between
$width: map-get($breakpoints, $bp2);
$width: $width - 0.02px;
@media screen and (min-width: #{map-get($breakpoints, $bp1)})
and (max-width: #{$width}) {
@content;
}
} @else if($type == pf){
@media (pointer: fine){
@content;
}
}
}
追加分はこうして
.hogehoge{
&:hover{
@include mq(pf) {
color: blue;
}
}
}
こうなる。便利。
@media (pointer: fine) {
.hogehoge:hover {
color: blue;
}
}
文字数に関する注意点
これで厄介なのが、@mediaは使うたびに生成される。一括にならない。
というのが、こうすると
.hoge{
@include mq(max, md) {
font-size: 19px;
color: red;
}
}
.hogehoge{
@include mq(max, md) {
font-size: 19px;
color: red;
}
}
@include mq(max, md) {
.hoge{
font-size: 19px;
color: red;
}
.hogehoge{
font-size: 19px;
color: red;
}
}
こうなる
@media screen and (max-width: 767.98px) {
.hoge {
font-size: 19px;
color: red;
}
}
@media screen and (max-width: 767.98px) {
.hogehoge {
font-size: 19px;
color: red;
}
}
@media screen and (max-width: 767.98px) {
.hoge {
font-size: 19px;
color: red;
}
.hogehoge {
font-size: 19px;
color: red;
}
}
文字数がめっちゃ増えてしまう。最初に書いたminifyでもまとめてくれない。
関数やら変数はjsと違って最初に宣言しておかないと引っ張れないので注意。だから別ファイルにまとめて@useで引っ張ってくるのが安心。
@useの注意点
コンパイラーによるのかもしれないけど。
こんな感じで用途別にファイルを作ったとする。
style.scss /* @useで他ファイルをまとめる */
_mixin.scss /* 関数用 */
_default.scss /* スタイルを書く */
_default.scss内で_mixin.scss内の関数を使用する、最終的に出力するのはstyle.cssだからそれらをstyle.scssにまとめるとする。
こうやる
@use "mixin";
@use "default";
関数を使うファイルで直接読み込む必要がある。
だめな例
@useと自身のファイルは結びついても@use同士を結びつけるのは無理みたい。
@use "mixin";
@use "default";
これでやれそうだけどダメ。多分、@use時に中身をcssに展開することが先行してるんだと思う。並べてから展開してくれたらいいんだけどね。
まとめ
cssを覚えたての人には地獄だけど、慣れてる人にはありがたい。
コンパイルが必要なのはしんどいけど環境が整えば全く関係ない。
作業ファイルと公開ファイルを分けられるので、軽量化に全ツッパできる。
コメント