開発室ブログ

Sass

Sassのお話

はじめまして、少し前に開発室に配属された者です。

さっそくですが、今回は Sass の話をしたいと思います。

Sass とは

簡単に言うとcss 拡張言語です。

本来の css で実現できないような事も Sass を使えばできます。(例えば条件分岐や繰り返しなど)

Sass で記述しても最終的に出力されるのは css ファイルなので、サーバー環境によって動かないということはありません。

ローカルで動くように環境を整えてあげるだけです。

Sass の2つの構文 ( Sass 構文 / Scss 構文 )

実はSassには Sass 構文 ( Sass syntax ) と Scss 構文 ( Scss syntax ) の2つの構文があるって知ってますか?

多分 Sass を使っている人なら殆どの人が知っている事だとは思うんですが、中には主流な Scss 構文しか知らない人もいるんじゃないかと思ってます。

Sass の中に Sass 構文と Scss 構文があるせいで、 Sass 構文 についてネットで調べようとすると大変困ります。

例えば「Sass 便利!使おう!」というタイトルのページを開いたら、中身は Scss 構文の事しか書いてないとかよくあります。

いや、まあ Scss 構文 も Sass の一部だから間違ってはいないんですけどね…。

個人的には Sass 構文結構好きなんですが、Sass 構文を調べようとして上記のようなパターンが多いので辟易としてしまいます。

Sass 構文 ( Sass syntax )

こっちが元々の Sass の書き方です。

  • 中括弧を使わずインデント(字下げ)でスコープを表す
  • コロンの後に必ず半角スペースを入れる
  • セミコロンを付けない

等のルールがあります。

Python やってる人とかは馴染みやすいんじゃないですかね。

cssとの書き方の違いに最初は戸惑うかもしれませんが、中括弧が不要だったり、mixinなどを省略記号で表せたりとこちらの構文のほうが書きやすいと思っています。

短い css なのと無理やり例を挙げようとして一部無駄なことをしているので、あまり Sass の恩恵は感じないかもしれませんが、下記のように記述することができます。

$textColor: #444444
$linkColor: #036eb7
$sublinkColor: #238ed7

=flexbox($direction: row, $align: center)
  display: flex
  flex-direction: $direction
  align-items: $align

=commonLink($color: $linkColor)
  a
    color: $color
    text-decoration: none

    &:hover
      opacity: 0.8

.class1
  +flexbox()
  color: $textColor

  +commonLink()

.class2
  +flexbox(column, flex-start)
  color: $textColor

  +commonLink($sublinkColor)

↓css変換後

.class1 {
  display: flex;
  flex-direction: row;
  align-items: center;
  color: #444444;
}
.class1 a {
  color: #036eb7;
  text-decoration: none;
}
.class1 a:hover {
  opacity: 0.8;
}
.class2 {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  color: #444444;
}
.class2 a {
  color: #238ed7;
  text-decoration: none;
}
.class2 a:hover {
  opacity: 0.8;
}

Scss 構文 ( Scss syntax )

インデントでのスコープ等がデザイナーの方に受けがわるかったのか、Sass 構文時代の Sass はあまり普及しなかったようです。

その後、経緯はわかりませんが、cssと同じような構文で書けるこの scss 構文が追加されました。

ネットで Sass って言われてるのは大体こいつの事です。忌まわしい。

cssと同じような構文で書けるため、cssからの移行が簡単です。cssをそのままコピペしても動きますしね。

先ほど Sass 構文で書いたものをそのまま Scss 構文で書くとこうなります。結果は同じなので割愛します。

$textColor: #444444;
$linkColor: #036eb7;
$sublinkColor: #238ed7;

@mixin flexbox($direction: row, $align: center) {
  display: flex;
  flex-direction: $direction;
  align-items: $align;
}
@mixin commonLink($color: $linkColor) {
  a {
    color: $color;
    text-decoration: none;

    &:hover {
      opacity: 0.8;
    }
  }
}

.class1 {
  @include flexbox();
  color: $textColor;

  @include commonLink();
}
.class2 {
  @include flexbox(column, flex-start);
  color: $textColor;

  @include commonLink($sublinkColor);
}

Sass 構文の問題点

ここまで書いてきた通り、私はどちらかというと Sass 構文のほうが好きです。

htmlを記述するためのテンプレートエンジンである pug を利用する場合は、pug も同じようにインデントでスコープを表現するので、似た書き方ができて作業がしやすいように思います。

ただ、そんな Sass 構文ですが、問題点があります。

Sass には map という機能があり、変数を配列のように扱う事ができます。

$listColor: (
  item1: #ffffff,
  item2: #eeeeee,
  item3: #dddddd,
  item4: #cccccc
);

@each $name, $color in $listColor {
  li.#{$name} {
    background: $color
  }
}

↓ css変換後

li.item1 {
  background: #ffffff;
}
li.item2 {
  background: #eeeeee;
}
li.item3 {
  background: #dddddd;
}
li.item4 {
  background: #cccccc;
}

繰り返し文と組み合わせることでこのように記述することができる為、この map 機能は大変便利なんですが、上記のコードは見てわかる通り Scss 構文です。

Sass 構文で同じように書くとエラーになります。

Sass 構文で map が使えないというわけではありません。

Sass 構文では map の記述中に改行ができません。

つまり Sass 構文で同じことをするためにはすべて一行に納める必要があります。

$listColor: (item1: #ffffff, item2: #eeeeee, item3: #dddddd, item4: #cccccc)

グエー!見辛い!

例では4つだからまだいいですが、これが10個とか20個とかあった場合はとんでもなく長い記述が1行に詰め込まれることになります。

この機能のために見やすさ重視で渋々 Scss 構文を使わざるを得なくなったりします。

色々調べると、同じ問題にぶち当たった方が海外にも大勢いるようで、その中に Sass の開発者に要望を上げている方が居ました。

英語力がないので意訳ですが、その要望に対する開発者の回答は

「その問題は気付いてるけど、直そうとすると Sass を根本から作り直さなきゃいけないから後回しで機能追加を優先させるよ」

でした。

希望はありませんでした。

私たちは Scss 構文と付き合っていかなくてはならないようです。つらい。

というところで今回のブログを終えたいと思います。

ありがとうございました。

RecentPost