この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
Rails3.1ではSCSSが標準で搭載されました。とても面白い仕組みなので紹介します。
CSSはWebページにおいて構造とデザインを分離するとても重要な仕組みです。しかし、デザインが複雑になるに連れてどんどん肥大化していき、うまくコントロールしないとメンテナンスが容易ではなくなってしまいます。よく、新しいデザインを追加したと思ったら他のデザインとぶつかってしまったなんてことがあったり、一箇所にクラスの定義がなくバラバラになっていて途方にくれてしまうなんてことはよくあります。
SCSSはこのような悩みをほどよく解決してくれるシンタックスを持つCSS用のメタ言語で、Rails 3.1から採用されました。SCSSについての詳細は、Sass、そしてSassy CSS (SCSS) をご覧ください。
今回は、黒田努氏のはじめる!Rails3(達人出版)のサンプルプログラム:hinagikuで、7.3 スタイルシートの作成に登場するサンプル(public/stylesheets/tasks.css)を例に、Rails 3.1でSCSSで記述した場合にどのような動きをするのかを紹介します。
書籍のサンプルでは、以下のようなコードになっています。
table.tasks {
width: 560px;
margin: 5px auto;
background-color: #eee;
border-collapse: collapse;
border-spacing: 0;
}
table.tasks tr {
border: solid 1px #ccc;
}
table.tasks td {
padding: 5px;
}
table.tasks col.name {
width: 320px;
}
table.tasks col.due_date {
background-color: #ddd;
}
これをSCSSで書きなおしてみます。
まず、書籍と同様にコントローラを作成します。
$ rails generate controller tasks
create app/controllers/tasks_controller.rb
invoke erb
create app/views/tasks
invoke test_unit
create test/functional/tasks_controller_test.rb
invoke helper
create app/helpers/tasks_helper.rb
invoke test_unit
create test/unit/helpers/tasks_helper_test.rb
invoke assets
invoke coffee
create app/assets/javascripts/tasks.js.coffee
invoke scss
create app/assets/stylesheets/tasks.css.scss
この時に、app/assets/stylesheets/tasks.css.scssも作成されます。
先ほどのCSSをapp/assets/stylesheets/tasks.css.scssに記述します。SCSSでは以下のようになります。
// Place all the styles related to the tasks controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
table.tasks {
width: 560px;
margin: 5px auto;
background-color: #eee;
border-collapse: collapse;
border-spacing: 0;
tr {
border: solid 1px #ccc;
}
td {
padding: 5px;
}
col.name {
width: 320px;
}
col.due_date {
background-color: #ddd;
}
}
このようにCSSで書きづらかった階層関係が非常にわかりやすく書くことができます。個人的に困っていたデザイナさんが作ってくれた新しいデザインを忙しいとかいう理由で一番下に追加して阿鼻叫喚とかいうことが、この階層化によって発生しづらくなっています。
さて、今まではCSSの指定は <%= stylesheet_link_tag :all %> として、public/stylesheets 以下のものを全て読み込む形になっていましたが、Rails 3.1からは、 <%= stylesheet_link_tag “application” %> となり application.css のみ標準で読み込む形になります。ということは、tasks.css はどこにいくのでしょうか?正解は、SCSSを利用してtasks.css.scssの内容が application.css に入るのです。
実際にこの仕組みをみてみましょう。
先ほど作成したコントローラにアクセスしてみます。
Started GET "/tasks" for 127.0.0.1 at 2011-08-09 14:10:51 +0900
Processing by TasksController#index as HTML
MONGODB hinagiku_development['tasks'].find({:done=>false})
Rendered tasks/index.html.erb within layouts/application (616.2ms)
Completed 200 OK in 678ms (Views: 677.1ms)
Started GET "/assets/application.css" for 127.0.0.1 at 2011-08-09 14:10:52 +0900
Compiled ~/develop/ruby/mongo_rails3_test/hinagiku/app/assets/stylesheets/tasks.css.scss (45ms) (pid 85886)
Compiled ~/develop/ruby/mongo_rails3_test/hinagiku/app/assets/stylesheets/application.css (1ms) (pid 85886)
Compiled ~/develop/ruby/mongo_rails3_test/hinagiku/app/assets/stylesheets/application.css (0ms) (pid 85886)
Served asset /application.css - 304 Not Modified (96ms)
Started GET "/assets/application.js" for 127.0.0.1 at 2011-08-09 14:10:52 +0900
Served asset /application.js - 304 Not Modified (19ms)
ここで、Compiledという文字があるとおり、コンパイルをしているということになります。
実際に出力されるCSSは以下のようになります。
/*
* This is a manifest file that'll automatically include all the stylesheets available in this directory
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
* the top of the compiled file, but it's generally better to create a new file per style scope.
*/
/* line 5, /Users/btm/develop/ruby/mongo_rails3_test/hinagiku/app/assets/stylesheets/tasks.css.scss */
table.tasks {
width: 560px;
margin: 5px auto;
background-color: #eee;
border-collapse: collapse;
border-spacing: 0;
}
/* line 12, /Users/btm/develop/ruby/mongo_rails3_test/hinagiku/app/assets/stylesheets/tasks.css.scss */
table.tasks tr {
border: solid 1px #ccc;
}
/* line 16, /Users/btm/develop/ruby/mongo_rails3_test/hinagiku/app/assets/stylesheets/tasks.css.scss */
table.tasks td {
padding: 5px;
}
/* line 20, /Users/btm/develop/ruby/mongo_rails3_test/hinagiku/app/assets/stylesheets/tasks.css.scss */
table.tasks col.name {
width: 320px;
}
/* line 24, /Users/btm/develop/ruby/mongo_rails3_test/hinagiku/app/assets/stylesheets/tasks.css.scss */
table.tasks col.due_date {
background-color: #ddd;
}
// Place all the styles related to the tasks controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
出力されたファイルはほとんど元の変換前と同じ内容になりました。すばらしい!
さて、今回 /assets/stylesheets にアクセスしているのに気をつけてください。以前では /stylesheets にアクセスしていたものが変わっています。これは、assetという仕組みを利用しているためで、config/application.rbから変更ができます。
# Enable the asset pipeline
config.assets.enabled = false
falseになっている場合は、以前と同様に public/stylesheets 以下を見に行くようになります。
SCSSは非常に面白い仕組みです。まさに幸福実現です。Sass、そしてSassy CSS (SCSS)には非常に多くの例があります。ぜひ、ご一読の上、Rails 3.1+SCSSの世界に飛び込んで下さい。
ちなみに、筆者はCoffeeScriptよく知らないので、そっちの方は別の人が記事にしてくれると期待しています。