Ruby on RailsプロジェクトにTailwind CSSを簡単に導入する方法
CSS(Cascading Style Sheets)がすべてのウェブサイトにとってどれほど重要であるか、いくら強調してもし過ぎることはありません。1996年末に最初のCSS標準が公開されて以来、機能面・エコシステム面ともに大きく進化してきました。
これまで数々のCSSフレームワークが登場し人気を博してきましたが、近年特に注目を集めているのがTailwind CSSです。
本記事では、まずTailwindの「ユーティリティファースト」というアプローチを解説し、その後、Ruby on Railsアプリケーションでの具体的な使い方を紹介します。Tailwindを活用すれば、カスタムCSSを大量に書いたり長時間のデバッグに悩まされたりすることなく、優れたウェブサイトを効率的に構築できることを実感いただけるはずです。
それでは始めましょう!
Tailwind CSS:ユーティリティファーストなアプローチとは
多くのCSSフレームワーク(Foundation、Bootstrap、Bulmaなど)は、ボタンやフォームフィールドといった完成済みコンポーネントを提供しており、それらのブロックを組み合わせるだけで素早くインターフェースを組み立てられます。
たとえば、Bootstrapでボタンを追加するコードは次のようになります。
この例では、btnとbtn-primaryというクラスを適用するだけで、シンプルなボタンが定義されスタイルされます。btn-primaryは用途に応じた適切な色を自動的に設定してくれます。しかし、既定のデザインが要件に合わない場合、すべてのコンポーネントを上書きするためのカスタムCSSスタイルシートを別途用意することになりがちです。
一方、Tailwindは「ユーティリティファースト」という考え方を採用しています。完成品のコンポーネントを提供する代わりに、低レベルの単一目的クラス(ユーティリティクラス)を多数備えており、それらを組み合わせて自由にカスタムデザインを構築できます。HTMLに直接事前定義クラスを記述していくため、カスタムCSSの必要性を最小限に抑えられ、ユーティリティクラスによる制約を通じてデザインの一貫性も保ちやすくなります。
つまり「ユーティリティファースト」とは、アトミックな単一目的クラスを組み合わせて複雑なデザインを構築していく手法のことです。
実際のコードでTailwindとBootstrapを比較してみましょう。まずは、Tailwindでシンプルなボタンをスタイリングする例です。
ここで設定しているボタン要素のクラスは以下の通りです。
- 背景色
bg-blue-500:「blue」はあらかじめ用意された色名で、末尾の数字で濃淡を指定します。数字が大きいほど色が濃くなります。 - ホバー時の背景色:
hover:bg-blue-600のように、擬似クラスも直感的に指定できます。 - 文字色
text-white:白のため数字は不要です。text-redのように数字を省略した場合もデフォルトの濃淡が適用されます。 - 上下パディング
py-2:「p」はpadding、「y」は縦方向、「2」はスペーシング値です。単位はピクセルではなく、Tailwind独自に定義されたスケールです。 - 左右パディング
px-4:同様に「x」は横方向を表します。 - 角丸:
roundedで角を丸くできます。
Bootstrapの例よりも冗長に見えるかもしれませんが、クラスを追加するだけでスタイルの細部を自在に調整でき、カスタムCSSクラスを作成する必要はありません。
既定の配色が気に入らない場合もご安心ください。カスタムカラーは後述する方法で簡単に追加できます。
スケールに関する補足
CSSはスペーシング(マージンやパディング)に関しては非常に柔軟で、ピクセルやrem(ルート要素のフォントサイズに対する相対単位)で細かく指定できます。ただし、その分だけ計算や管理が煩雑になりがちです。そこでTailwindには独自のスペーシングスケールが組み込まれており、複雑さを隠蔽しつつ、デザイン全体の比率の整合性も保てるようになっています。
デフォルトでは、Tailwindは0〜96までの値を提供し、各ステップが互いに比例関係にあります。たとえば、値16は8のちょうど2倍のスペーシングになります。このおかげで、remやピクセルを自力で換算する必要はなく、好みの値を一度決めればデザイン全体で一貫して再利用できます。
スペーシングの詳細については、Tailwind CSS公式ドキュメントを参照してください。
Ruby on Rails環境へのTailwindのセットアップ
Ruby on Rails 7.xでは、アプリケーションジェネレーターがTailwindを直接サポートしています。
本記事では話題を絞るため、テスト関連の設定をスキップするオプション(-T)を付けています。
Tailwindには、アプリケーションが実際に必要とするCSSファイルだけを生成する便利な機能があります。他のフレームワークでは、未使用の部分まで含めたフレームワーク全体のCSSファイルを読み込む必要がありますが、Tailwindはプロジェクトをスキャンし、使用されているクラスのみを含むCSSファイルを自動生成します。その結果、読み込み時間の短縮とビルド時間の最適化が実現します。
この仕組みを利用するには、専用のユーティリティを実行します。開発モードでは、作業内容に合わせて常時更新を行うウォッチャーデーモンを起動できます:bin/rails tailwindcss:watch
また、このウォッチャーをProcfileに登録すれば、foremanやovermindを使ってwebとcssの各プロセスをまとめて起動できます。
それでは、シンプルなランディングページで試してみましょう。
ブラウザで https://localhost:3000/landing/index にアクセスします。
ランディングページのコード解説
すべてのランディングページにはタイトルが必要です。アプリケーションをTailwind使用前提で作成したので、ジェネレーターが出力したコードはそのまま動作します。
一見すると普通のHTMLに見えますが、h1タグにはわずか2つのクラスしか指定していません。
font-bold:フォントの太さを制御します。text-4xl:フォントサイズを制御します。
試しにtext-4xlをtext-xlへ変更してページを再読み込みすると、新しいスタイルが即座に反映されます。Foremanの稼働しているターミナルを見ると、Tailwindがバックグラウンドでスタイルシートを自動再生成したことが確認できます。
このように、Ruby on RailsアプリケーションへのTailwindの統合は非常にシンプルです(内部ではtailwindcss-rails gemが活躍しています)。
Ruby on Rails向けのTailwind設定
config/tailwind.config.jsファイルを編集することで、Tailwindの各種設定を調整できます(独自カラーの追加、フォントの指定、スペーシングの変更など)。
たとえば、背景や文字に使える「copper(コッパー)」という色を追加してみましょう。
なお、濃淡は数字で表す代わりに任意の名前を付けることも可能です。3つの濃淡だけで足りるのであれば、ビュー側では'light'、'medium'、'dark'のような名前を使うと可読性が向上します。
詳細については、tailwindcss-rails gemのREADMEおよびTailwind CSS公式ドキュメントをご参照ください。
アセットパイプラインとの連携
ローカル開発環境ではbin/rails tailwindcss:watchがスタイルシートを常に最新に保ってくれることを紹介しました。一度だけビルドしたい場合は、bin/rails tailwindcss:buildを使用します。
本番環境向けには、bin/rails assets:precompileが内部的にbin/rails tailwindcss:buildを呼び出すため、通常のRailsのアセットプリコンパイルの流れにそのまま乗せられます。
Ruby on Railsのアセットパイプラインについて詳しく知りたい方は、公式ガイドを参照してください。
RailsでのTailwind実践例
ここからは、実際のビューにおけるTailwindの実践的な活用例として、「フォーム」と「レスポンシブナビゲーションバー」の2つを見ていきましょう。
シンプルなフォームのスタイリング
まず、Ruby on Railsのジェネレーターでuserリソースを作成します。
続いてusers_controller.rbを編集し、フォーム用のビューを作成します。
このように、文字色・背景色・ボーダー・パディング・マージンなどを要素ごとに個別調整しています。特別なテクニックは一切使わず、標準的なTailwindクラスの組み合わせだけで、要件に合わせたフォームを自由にカスタマイズできます。
レスポンシブナビゲーションバー
Tailwindでは、任意のユーティリティクラスにブラウザの最小幅を条件とするブレークポイントを組み合わせられます。たとえば、次のタイトルはウィンドウサイズによって表示色が変化します。
デフォルトでは濃いグレーで表示され、ブラウザ幅が640px〜1024pxの間ではティール系の色に、1024pxを超えると紫系の色に変わります。
Tailwindはグリッドカラムも柔軟に扱えるため、ウィンドウサイズに応じて要素のカラム幅が変化する例も紹介します。
この場合、「State」というラベルは画面幅に応じて2列または3列にまたがって表示されます。
ここでは、Tailwindのグリッドレイアウトユーティリティを使い、次のようなグリッドを定義しています。
- デフォルトは1カラム(
grid-cols-1) - 幅640px超では6カラム
- 幅768px超では8カラム
Tailwindの標準ブレークポイントとその幅は以下の通りです。
sm:640pxmd:768pxlg:1024pxxl:1280px2xl:1536px
このように、Tailwindを活用すればページデザインやコンポーネントのスタイリングが格段にシンプルになります。
Tailwindと他フレームワークの違い
Tailwindの基本的な使い方が理解できたところで、他のCSSフレームワークとの主な違いを整理しておきましょう。
- ユーティリティベース:特定のCSSクラスを組み合わせて各要素のスタイルを構成します。それぞれのクラスはスタイルの異なる側面に特化しています。
- 必要なものだけを出力:サイトの公開に必要なクラスだけが生成されるため、読み込み時間が短縮され、ビルド時間も最適化されます。
- 高い拡張性:シンプルな設定ファイルひとつで、Tailwindのデフォルト設定を拡張・カスタマイズできます。
- 簡単な色の濃淡調整:ホバー状態のために明るい色や暗い色を自分で作り出す必要がありません。
- シンプルなスペーシング:内部で完結する比例スケールにより、余白の管理が容易になります。
- カスタムCSSの削減:クラスを組み立てるだけでスタイリングが完結するため、カスタムCSSへの依存が減り、HTMLファイルやスニペット単位でスタイル(テーマ全体を含む)を共有できます。
- Ruby on Railsとの親和性:tailwindcss-rails gemのおかげで、レイアウトやアセットパイプラインへの統合がすべて自動化されています。
まとめ
見てきたように、TailwindのユーティリティファーストなアプローチはRuby on Railsと非常に相性が良いことがお分かりいただけたと思います。複雑なカスタム設定や大量のカスタムCSSを追加して環境を調整する時間は不要です。ビューやパーシャルを設計しながら、その場でTailwindのユーティリティクラスを使って形とスタイルを整えられます。
さらに学びたい方には、活発なコミュニティによる豊富なテンプレートやコンポーネント、そしてTailwind開発元が提供するTailwind UIなどの商用製品もおすすめです。
ハッピーコーディング!
P.S. Ruby Magicの新着記事をいち早くお読みになりたい方は、ぜひRuby Magicニュースレターをご購読ください。記事を見逃すことはもうありません!
Thomas Riboulet(トーマス・リブレ)
ゲスト執筆者のThomasは、フランスを拠点とするバックエンドおよびクラウドインフラストラクチャエンジニアのコンサルタントです。13年以上にわたり、スタートアップや企業と協働し、チーム・製品・インフラストラクチャのスケーリングに取り組んできました。フランスのGNU/Linux専門誌や自身のブログでも度々執筆しています。
-
Rubyで学ぶNLP:Nグラム分析の楽しさと実践
大量のテキストデータが手元にあり、そこから何らかの意味を抽出したい——そんな場面に遭遇したことはありませんか? そんなときにまず試したいのが、テキストをNグラム(n-gram)に分割するという手法です。 Nグラムとは何か? Wikipediaには次のように定義されています。 計算言語学および確率論の分野において、n-gramとは与えられたテキスト列から取り出した、n個の連続した要素からなる列のことである。—— Wikipedia 具体例を見てみましょう。 Hello there, how are you? というフレーズを例にとると、ユニグラム(1要素のNグラム)は Hello, there,
-
VCR Gem × WebMockでRubyのテストスイートを高速化する方法
Rubyアプリケーションが外部APIを利用しているなら、テストが遅い・APIのレート制限に引っかかるといった問題に直面したことがあるのではないでしょうか。 解決策は何があるでしょう? クライアントライブラリのHTTPメソッドを手動でスタブ化し、事前に用意したレスポンスを返す方法もあります。 しかし、これは手間がかかる上に、コードも読みにくくなってしまいます。 より良い解決策は、WebMock + VCRという強力なGemの組み合わせを使うことです。 WebMockは、主要なHTTPライブラリからのHTTPリクエストを横取り(インターセプト)します。対応しているのは例えば: net/http