概要
Railsのプロジェクトにおけるスタイルシートの場所、スタイル設定について整理する。
デフォルトの状態
プロジェクト生成直後、app/assets/stylesheets/ディレクトリーにapplication.cssが生成され、以下の2行が記述されている。これらの行はディレクティブと呼ばれ、それぞれの意味については後述。
1 2 |
*= require_tree . *= require_self |
この段階でRailsの”Yay! You’re on Rails!”のページのソースを見ると、HTMLに直接styleタグが書かれている。
コントローラーとスタイルファイルの関係
以下のように2つのアクションを含むコントローラーを3つ生成する(出力は省略)。
1 2 3 |
[vagrant@vagrant dummy_app]$ rails generate controller fruits orange grape [vagrant@vagrant dummy_app]$ rails generate controller vesitables beets carrots [vagrant@vagrant dummy_app]$ rails generate controller meats pork beef |
その結果、コントローラー・ビューファイルとともに、app/assets/stylesheetsディレクトリーに3つのscssファイルが生成される。
1 2 |
[vagrant@vagrant dummy_app]$ ls app/assets/stylesheets/ application.css fruits.scss meats.scss vesitables.scss |
これら3つのscssファイルはコメントのみの空の内容。
1 2 3 |
// Place all the styles related to the fruits controller here. // They will automatically be included in application.css. // You can use Sass (SCSS) here: http://sass-lang.com/ |
ここでorangeビューファイルを表示させてみる。
localhost:3000/fruits/orange
表示されたページのソースのうちスタイルシートの読み込みに関する行を抜き出すと以下のとおり。
1 2 3 4 |
<link rel="stylesheet" media="all" href="/assets/fruits.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload" /> <link rel="stylesheet" media="all" href="/assets/meats.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload" /> <link rel="stylesheet" media="all" href="/assets/vesitables.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload" /> <link rel="stylesheet" media="all" href="/assets/application.self-f0d704deea029cf000697e2c0181ec173a1b474645466ed843eb5ee7bb215794.css?body=1" data-turbolinks-track="reload" /> |
以下のことがわかる
- applicationのほか、新たに生成されたfruits, vesitables, meatsに関するスタイルシートが全て読み込まれる
- スタイルシートはcss拡張子を持つ
- ファイル名の本体は、
コントローラー名.self-ダイジェスト
の形式 - URLクエリーパラメーターを持つ(
body=1
) - スタイルが読み込まれる順番は、application.cssが最後で、その前に他のファイルが辞書順で読み込まれる
これらのファイルは元のscssファイルからcssにコンパイルされた結果で、ファイルの内容のダイジェストが元のファイル名に付加されている。
この場合、application.cssと3つのscss全てのスタイルが適用される。たとえばいずれかのcss/scssファイルに* { color: red; }
と記述するとfruits/orangeページの文字の色が赤くなる。
require_selfとapplication.css
無指定でもapplication.cssは読み込まれる
application.cssの以下の2行を削除し、何も指定されていない状態にする。
1 2 |
*= require_tree . *= require_self |
この状態でorangeページを表示させてソースを見ると、application.cssの読み込みだけ残っている。
1 |
<link rel="stylesheet" media="all" href="/assets/application.self-34004ed1a95199bac37fb11583f3acbb08d69e689d5c114362d79071d479a29f.css?body=1" data-turbolinks-track="reload" /> |
require_selfの意味?
application.cssの2行の記述のうち*= require_tree .
の行を削除し、ページを表示させてソースを見てみる。
1 |
<link rel="stylesheet" media="all" href="/assets/application.self-18157c666aa5f54338350dab22122fa53c8af29b5f90ea4c5accdda9cc63283f.css?body=1" data-turbolinks-track="reload" /> |
*= require_self
の行に対応してapplication.cssのファイルが読み込まれているが、そもそもなにも指定しなくてもこの行は生成されていた。
次に*= require_self
の方を削除し*= require_tree .
を残した結果を見てみる。無指定の時と同じく、ここでもapplication.cssが読み込まれている。
1 2 3 4 |
<link rel="stylesheet" media="all" href="/assets/fruits.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload" /> <link rel="stylesheet" media="all" href="/assets/meats.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload" /> <link rel="stylesheet" media="all" href="/assets/vesitables.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload" /> <link rel="stylesheet" media="all" href="/assets/application.self-18157c666aa5f54338350dab22122fa53c8af29b5f90ea4c5accdda9cc63283f.css?body=1" data-turbolinks-track="reload" /> |
読み込み順の制御は可能
require_treeとrequire_selfの順番を逆にしてみる
1 2 |
*= require_self *= require_tree . |
そうすると、application.cssが最初に読み込まれるようになった。
1 2 3 4 |
<link rel="stylesheet" media="all" href="/assets/application.self-f0d704deea029cf000697e2c0181ec173a1b474645466ed843eb5ee7bb215794.css?body=1" data-turbolinks-track="reload" /> <link rel="stylesheet" media="all" href="/assets/crops/fruits/fruits.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload" /> <link rel="stylesheet" media="all" href="/assets/crops/vesitables.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload" /> <link rel="stylesheet" media="all" href="/assets/meats.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload" /> |
ディレクティブ
require_tree
stylesheetsディレクtリーの構成を以下の様に変更する。
d:stylesheets
f:meats.scss
d:crops
f:vesitables.scss
d:fruits
f:fruits.scss
この状態でapplication.cssが初期設定のとき、ページを表示させてもスタイルファイルの読み込みは変わらない。
require_tree .
はカレントディレクトリー以下のすべてのディレクトリをたどりながらすべてのファイルをCSSに含める。
次にapplication.cssの内容を以下の様に変更する。
1 |
*= require_tree ./crops |
この結果、指定したcropsディレクトリー以下のファイルが再帰的に読み込まれる(application.cssは読み込まれている)。
1 2 3 |
<link rel="stylesheet" media="all" href="/assets/crops/fruits/fruits.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload" /> <link rel="stylesheet" media="all" href="/assets/crops/vesitables.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload" /> <link rel="stylesheet" media="all" href="/assets/application.self-18157c666aa5f54338350dab22122fa53c8af29b5f90ea4c5accdda9cc63283f.css?body=1" data-turbolinks-track="reload" /> |
require_directory
require_directoryは、指定したディレクトリー下のファイルのみをCSSに含める。サブディレクトリー以下は無視される、
1 |
*= require_directory ./crops |
この結果は、cropsディレクトリー下のvesitables.cssファイルのみが読み込まれる(application.cssは読み込まれている)。
1 2 |
<link rel="stylesheet" media="all" href="/assets/crops/vesitables.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload" /> <link rel="stylesheet" media="all" href="/assets/application.self-18157c666aa5f54338350dab22122fa53c8af29b5f90ea4c5accdda9cc63283f.css?body=1" data-turbolinks-track="reload" /> |
require ファイル
requireディレクティブにファイル名を指定して、特定のファイルのみを読み込める。
1 |
*= require ./crops/fruits/fruits.css |
上記の指定で、HTMLファイルにはfruits.cssのみが読み込まれる(application.cssは読み込まれている)。
1 2 |
<link rel="stylesheet" media="all" href="/assets/crops/fruits/fruits.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload" /> <link rel="stylesheet" media="all" href="/assets/application.self-18157c666aa5f54338350dab22122fa53c8af29b5f90ea4c5accdda9cc63283f.css?body=1" data-turbolinks-track="reload" /> |