Sassで行こう!

Translation of: Getting Started with Sass - A List Apart

Getting Started with Sass

CSSの持つその簡明さは欠かせない特徴の一つで、それは最も歓迎されている点でした。CSSによるスタイルシートは、セレクターといくつかの適用したいスタイル情報を含むルールを羅列したものに過ぎません。しかし、WebサイトやWebアプリケーションが巨大に、そして複雑になり、様々なデバイスや画面サイズに対応せざるを得なくなった現在、この簡明さという特徴―fontタグやテーブル・レイアウトの淘汰に大いに役にたったもの―が大きな足かせになっています。

簡単な計算機能や変数を追加するなどといったCSSの修正案が過去に提示されましたが、どれもブラウザー・ベンダーには採用されませんでした。仮にこういった新しく素晴らしい拡張されたCSSがあるブラウザーに実装されたとしても、それが実用に耐える程度に全てのブラウザーで対応されるようになるまではかなりの年月を要するでしょう。

幸運なことに何年か前にHampton CatlinNathan Weizenbaumにより複雑なスタイルシートをメンテナンスする良い方法が提案されています。ブラウザーが新しいCSSにまだ対応していなくても、複雑なCSSを書くために新しい文法を積極的に使用し、それをプリプロセッサー(サーバーかローカル環境で動かすプログラム)によって既存のCSSの文法に合うように変換すれば良いのではないかとこの二人は気づいたのです。

彼らが開発した新しいスタイルシートの文法はsyntactically awesome style sheetを略してSassと言います。当初のSassの文法は、中括弧がなかったりプロパティは決まった数の半角スペースでインデントして書くというもので(そうしないとコンパイラーがエラーを吐きます)、通常のCSSの文法とはかけ離れたものでした。このことはプログラマー(新たな文法を学ぶことの苦痛を楽しむことが出来る人達)にとってはあまり問題ではありませんでしたが、多くのWebデザイナー達はよく知っているCSSからかけ離れたSassに近寄ろうとはしませんでした。これはつまり実用上の問題です。Sassのインデント・ベースの文法は既存のCSSとまったく互換性がないので、かなりの時間をかけて古いCSSコードをSassに変換することでようやくその恩恵に預かれるということになります。それでは巨大なWebサイトにおいて採用するのは難しかったということです。

Sass 3.0において新しくCSSによく似た文法、Sassy CSS、略してSCSSが導入されました。SCSSはCSSの「完全な上位互換」とか「メタ言語」などとオタク共が呼ぶようなものにあたり、それはつまりあらゆるValidなCSSはValidなSCSSであるということを意味します。言葉を変えて言うと、全てのあなたが書いたスタイルシートはSassのプロセッサーを通るので、この新しい言語を完全に覚えなくても一部でちょっとその機能を使ってみたりすることも可能というわけです。

通常のCSSと違いSassのSCSSはスクリプト言語で、式や関数・変数・制御構文・ループなどをサポートしています。Sassの恩恵を享受するためにそのすべてを使う必要は特になく、必要な時に必要な場所で使用すれば良いだけです。巨大なプロジェクトにおいてCSSは複雑であるか単調な繰り返しになりやすいですが、それを効率的に書くことができるようになるでしょう。

この記事では実際にいくつかの機能の使い方を具体的に説明し、SassとSCSSで何ができるのかということのとっかかりを示そうと思います。Sassについてもっと詳しく知りたい場合は最後に載せる参考リンクや書籍を参照してください。

わかりやすくそして簡便にするために、以下例示するコードはコンパイルしたCSSコードではなくSCSSのコードのみに統一してあります。Sassがどのように機能するかを覚えるにはSCSSでスタイルを書いてどうコンパイルされるか実際にやってみるのが良いでしょう。参考としてGitHubにこの記事で取り上げた全てのコードがあります。それをコンパイルしたCSSもあるので、これら気の利いた機能によって書かれたSCSSがどのように実際に使うことの出来るCSSへと変換されるかも参照できます。

Getting started

SassはRubyで書かれており、Rubyのパッケージ・マネージャーであるRubyGemsから入手することができます。Ruby (とコマンド・プロンプトやターミナル)のことを少し知っているのなら、インストールについてはSassのWebサイトを参照するのが良いでしょう。

あまりコマンド・ラインに詳しくない人やすぐさまSassを動かしたいというような人には、ScoutというWindowsでもMacでも動作するRubyとSassコンパイラーが内蔵されたAIRアプリケーションがあります。

sassというコマンド・ラインのツールもScoutも編集中のSCSSファイルの更新を監視し、自動的にCSSへと変換するものです。Sassファイルがあるディレクトリ(フォルダー)がinput folderでCSSファイルを出力したい場所がoutput folderになります。これらのフォルダーはinput folderの中にoutput dfolderがあっても、あたはその逆でも構いません。通常は以下のように通常スタイルシートを配置するフォルダーの下にscssという名前(僕はこの名前をよく使いますが、別に何でも構いません)でフォルダーを作ると良いでしょう:

my_project/
  index.html
  css/
    main_style.css
    scss/
      main_style.scss
      _mixins.scss
      _colors.scss

このscssフォルダーにアンダースコア(_)で始まるファイルがありますが、これをpartialと呼びます。名前の通り「部分的な」スタイルシートで、メインとなるSCSSファイルにインポートして使う小さなSCSSコードが詰まったものです。partialについてはこれからちゃんと説明しますが、どこに置くと良いかはわかったと思います。

Use partials to organize your code

CSSには既に@importにより別のまたは外部のWebサイトのスタイルシートを読み込む機能があります。開発者の中には巨大なプロジェクトのスタイルを論理的に整理して分け、これを使って読み込ませるという方法を取ることを好む人もいます。例えばmain_style.cssでは以下のように@importでページごとのスタイルシートを読み込むだけなどということもできます:

@import url('/shared/global.css');
@import url('/pages/home.css');
@import url('/pages/blog.css');

しかし今日ではこれはあまり良い手法だと考えられていません。なぜならインポートするごとにHTTPリクエストとその読み込みがブラウザーで行われるため、Webサイトの読み込みが遅くなるからです。またYSlowやGoogle Page Speedのスコアも下がるでしょう。

Sassでは巨大なスタイルシートをpartialに分割でき、@import (CSSのそれとは少し違いますが)を使ってそれらを参照することができます。そうするとメインとなるSCSSファイルを更新した時、そのインポートしたpartialは出力されるCSSファイルにマージされます。(ただしURLを指定してインポートした場合は通常のCSSのそれと同じように動作します。)

@import 'shared/global';
@import 'pages/home';
@import 'pages/blog';

これをコンパイルすると全てのスタイルを含む一つのファイルになります。Sassでは更に読み込み速度の最適化のためにCSSの出力から空白や改行を削除して圧縮することもできます。

ひとつだけ注意することがあります。それはpartialは少し特別なSCSSファイルで、通常のスタイルシートのようには扱えません。ひとまとめにしたいコードは必ず全てメインのスタイルシートで@importしなければなりません。またpartialのファイル名はアンダースコア(_)で始めます。例えば上記コードではpages/homeというpartialを読み込んでいますが、そのファイルはpages/_home.scssという名前でなくてはなりません(このパスは常にメインのSCSSファイルに対する相対パスである必要があります)。このアンダースコアによってSassのコンパイラーはそのファイルがpartialなのかどうかを知ることができ、それによってCSSに変換すべきではないということを判断します。この制限はそれぞれのpartialに意図を持たせて論理的に整理することができることとの妥当なトレード・オフだと思います。

Don’t repeat yourself

これでスタイルシートを整理することができました。次にCSSが単調な繰り返しにならないようにしてみましょう。

Sassの最も素晴らしい機能の一つはルールのネストです。通常のCSSファイルでは全てのルールが並列に並べられています。そしてそれぞれのルールのセレクターはその構成する要素を全て書く必要があります:

body.home .media-unit {
  border: 1px solid #ccc;
  background-color: #fff;
}
body.home  .media-unit .right {
  border-left: 1px solid #ccc;
}
body.home .media-unit .right h1 {
  font-size: 24px;
}

とても、そうですとても、単調な繰り返しであることに加え、このコードではHTML要素をどのような意図を持ってスタイリングしようとしているかを理解させることは難しいでしょう。ネストすることによってSCSSのコードから冗長な部分が省かれ、より把握しやすくなります:

body.home {
  .media-unit {
    border: 1px solid #ccc;
    background-color: #fff;
    .right {
      border-left: 1px solid #ccc;
      h1 {
        font-size: 24px;
      }
    }
  }
}

これをコンパイルすると上記CSSと同じコードを得られます。残念ながらこのコンパクトな文法によって出力されるCSSファイルを小さくしたり読み込みを速くしたりすることはできませんが、セレクターをネストすることによってコードをスッキリとさせ、論理的に整理することが出来るので、以前よりもずっと、そしてこれからもずっとメンテナンスしやすくなるでしょう。

Sassではセレクター以外にもmedia queriesをネストすることができます。これによってどのようなスタイルが適用されるかを把握しやすくなるでしょう:

.container {
  width: 940px;

  // If the device is narrower than 940px, switch to
  // a fluid layout
  @media screen and (max-width:940px) {
    width: auto;
  }
}

SassはこのようなファイルをどうすればValidなCSSにできるかをちゃんとわかっているので、この場合は.containerセレクターをmedia queryルール内へとコピーしてCSSに変換します:

.container {
  width: 940px;
}

@media screen and (max-width:940px) {
  .container {
    width: auto;
  }
}

Variables

Sassの変数が素晴らしいのは二つの理由があります。ひとつは変数によって重複するコードを減らすことができ、簡単に変更を加えることができるようになることです。これが最も大事な理由です。もう一つは色のような値に特別な名前を付けることによって、そのスタイルがどのような意図を持ったものなのかをわかりやすくすることができるようになることです。

TypekitではそのUIでコーポレート・カラーである緑、#99cc00または「Typekit green」と呼んでいる色を使用しています。この色はボタンから見出しの色までとてもたくさんCSSに出てきます。もしコーポレート・カラーをTypekit greenから別の色に変更しようとした場合、その全てを変更するには多大な労力が必要となるでしょう。16進数のコードの代わりに変数を使うことによって、その変数(スタイルシートの先頭もしくはpartialで設定します)を変更するだけで、新しい色が使われるようになります。変数を変数を使って定義することも出来るので、それによってもっとスタイルシートを意味づけされたものにすることができます:

$typekit-green: "#99cc00";
$typekit-link-color: $typekit-green;

a {
  color: $typekit-link-color;
}

色の16進数コードに限らず大抵の値を変数として定義することが出来ます。フォント・ファミリをまとめたものにはもってこいでしょう:

$sans-serif-font: 'ff-dagny-web-pro', 'Helvetica Neue', Arial,
Helvetica, 'Liberation Sans', sans-serif;
$serif-font: 'ff-tisa-web-pro', Georgia, Times, serif;

.banner h1 {
  font-family: $sans-serif-font;
}

Mixins

ミックスインはプロパティやルールのセットで再利用可能なものです。これは単に読み込むだけではなく、他のルールと「ミックス」することもできます。定義するには@mixinというキーワードを使い、読みこむ時には@includeというキーワードを使います。

以下の例ではSassにhighlighted-bold-textというミックスインに含まれる全てのスタイルを.result-with-highlights以下にある全てのspan要素に適用してもらうということになります:

$highlight-color: #ffa;

@mixin highlighted-bold-text {
  font-weight: bold;
  background-color: $highlight-color;
}

.result-with-highlights {
  span {
    @include highlighted-bold-text;
  }
}

一旦ミックスインを定義したら同じファイルのどこでも何回でも利用することができます。例えばhighlightedというクラス名を持つ要素にもミックスインで定義済みのcolorfont-weightプロパティを適用することができます:

.highlighted {
  @include highlighted-bold-text;
}

ミックスインはCSS3の新しいプロパティを要素に適用する時にとても便利です。それらは各ブラウザ間での互換性のためにベンダー拡張プリフィックスとフォールバックが必要になるからです。CSSでは通常、同じようなコードのコピー・アンド・ペーストを繰り返して対応することになるため非常に面倒なものです。Sassのミックスインではそういった新しいプロパティをあまりコードを書かずに利用することができ、将来の互換性もある程度確保することができます。

以下のコードは4pxの角丸を要素に適用するミックスインです。WebKitやFirefox、そしてIEのベンダー拡張プリフィックス、更にWeb標準であるCSS3仕様で定義されているborder-radiusプロパティを使っています。また角丸の度合いを変数にすることによって後からも簡単にその度合いを調節できるようにもしています:

@mixin rounded-corners {
  $rounded-corner-radius: 4px;
  -webkit-border-radius: $rounded-corner-radius;
  -moz-border-radius: $rounded-corner-radius;
  -ms-border-radius: $rounded-corner-radius;
  border-radius: $rounded-corner-radius;
}

.button {
  @include rounded-corners;
}

ミックスインはプロパティーだけでなく、ネストされたルールを抱合することも出来ます。例えばよく知られているclearfixハックをSassのミックスインとして定義する場合はこうなります:

@mixin clearfix {
  // For modern browsers
  &:before,
  &:after {
    content:"";
    display:table;
  }

  &:after {
    clear:both;
  }

  // For IE 6/7 (trigger hasLayout)
  & {
    zoom:1;
  }
}

.group {
  @include clearfix;
}

アンパサンド(&)というセレクターはSassにおいて「そのセレクター」を意味します。つまりこのコードをコンパイルすると全ての&をこの場合は.groupに置換してCSSへと変換してくれます。

Making stylesheets smarter

ミックスインを使って簡単なスタイルを適用するだけでも結構便利ですが、JavaScriptやPHPのようにミックスインで引数を使うようになるととてつもなく便利になります。引数と組み合わせて制御構文や関数を駆使することにより複雑で巨大なスタイルシートを効率良く管理することができるでしょう。

グリッド・レイアウト・システムなどはSassにもってこいです。既に簡単に使える960pxベースのCSSグリッド・システムがいくつもありますが、それらの多くは無意味なクラス名をHTMLに埋め込むことを強要します。それにあまり周知されていませんが、それらのCSSグリッド・システムを利用する場合、その中のごく一部の定義だけを利用したい場合でもそのシステムのCSSを全て読み込む必要があります。

この最後の例では単純な12カラムのグリッドをSassで実装してみます。グリッドそれぞれをクラス名として定義するのではなく、ミックスインによって幅と余白をグリッドに沿うように調節したいと思います。

まずはカラムとその間隔の幅を変数として定義します:

$column-width: 60px;    // 12 columns = 720px
$gutter-width: 20px;    // 11 gutters = 220px

つづいてSassに計算させる必要があるので、その式を考えます。それぞれのグリッドは指定した数のカラムとそのそれぞれの間にある間隔を加えたものになるので、その幅の計算は以下のような式で求められるでしょう:

幅 = (カラムの幅 × 数) + (間隔の幅 × (数 – 1))

ではミックスインにとりかかりましょう。今までの例とは違いこのミックスインは引数として「カラムの数」を取ります。引数はミックスイン内で変数と同じように扱えます。グリッドは全て左にフロートさせ、カラムの間隔の幅分右にマージンをとります:

@mixin grid-unit($span) {
  float: left;
  margin-right: $gutter-width;
  width: ($column-width * $span) + ($gutter-width * ($span - 1));
}

簡単なものでしょう? しかしまだこの僅かなコードの本領は発揮されていません。この簡単なミックスインにより、2/3をコンテンツが残りをサイドバーが占めるベーシックなレイアウトを簡単に、そしてよりわかりやすいクラス名を使って作ることができます:

.container {
  @include clearfix;
  @include grid-unit(12);
  float: none;
  margin: 0 auto;
}

.main-content {
  @include grid-unit(8);
}

.sidebar {
  @include grid-unit(4);
  margin-right: 0;
}

これがどれくらい価値があるか―僕は最近のプロジェクトではだいたいこのグリッドを計算するミックスインのバリエーションを使っています―は、これがSassのできることのうちごくわずかなものでしかないことからわかるのではないでしょうか。

Sassのサポートする基本的な関数群により可変幅のレイアウトも簡単に作成することができます。Ethan Marcotteが編み出した可変幅の計算式を利用して、上記のベーシックなレイアウトのレスポンシブなバージョンを作ってみます。Sassは指定されない限りCSSの単位を適当に変換してくれたりはしないので、ビルトインのpercentage()関数を使って変換します:

.container {
  // result = target / context
  width: percentage(940px / 960px);

  .main-content {
    // This is nested inside of .container, so its context is 940px
    width: percentage(620px / 940px);
  }

  .sidebar {
    width: percentage(300px / 940px);
  }
}

色を変換したり調整したりする関数もあります。暗くしたり明るくしたり、透明度や彩度を調整したり、全てスタイルシートの中で行うことができます:

$base-link-color: #00f;
a {
  color: $base-link-color;
}
a:visited {
  // This reduces the lightness of the color (in HSL terms)
  // by 50%, leaving hue and saturation alone
  color: darken($base-link-color, 20%);
}

figcaption {
  // Generates an rgba() color value with 50% opacity
  background-color: transparentize(#fff, 50%);
}

もしこれらビルトインの関数では物足りない場合、自分で定義してpartialのように複数のプロジェクトで使いまわせるようにすることもできます。詳しくはビルトイン関数の一覧を参照して何ができるかそしてできないのかを把握してください。

What's next?

Sassの公式WebサイトにはSCSSの完全なリファレンスを始めとした多くの有益な情報があります。例えばSCSSに対応したエディタのプラグイン一覧などはその最たるものでしょう。これらを導入することによって構文強調や入力補助を自分のエディターで行えるようになるかもしれません。

更には開発者であるHampton CatlinによってSassの詳しい解説本が書き上げられたところです。Pragmatic ProgrammersのWebサイトでは既にベータ版のeBookを発売済みです。

Chris Eppsteinが作成したCompassというSCSSの関数やよく使うパターンをまとめたライブラリもあります。このライブラリにはEric MeyerのリセットCSSやBlueprintフレームワーク、更には数多くのCSS3サポートやタイポグラフィー・パターンが含まれており、「スタイルシートのjQueryだ」という開発者たちの説明はまさに的を射たものです。もしScoutを利用している場合はCompassフレームワークは既にインストールされています。そうでない場合はCompassのWebサイトのインストール手順を読んでインストールしましょう。