Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

RailsでTailwind CSSを使う方法|導入から実践的なスタイリングまで徹底解説

CSSは魔法のような存在ですが、同時に時間のかかる作業でもあります。美しく、機能的で、アクセシブルなサイトは使っていて心地よいものですが、自分でCSSを一から書くのは骨の折れる仕事です。近年はBootstrapをはじめとする多くのCSSフレームワークが登場し、その中でもTailwind CSSは特に注目を集めています。

RailsにはTailwindが標準搭載されていませんが、この記事では新しいRuby on RailsプロジェクトにTailwind CSSを追加する方法を解説します。これにより、デザイン実装にかかる時間を大幅に節約できるでしょう。さらに、Tailwindのユーティリティクラスを使ったデザイン手法も実際に見ていきます。前半では新規Railsプロジェクトの作成から最初にTailwindを組み込む手順を、後半では既存プロジェクトへTailwindを追加する方法を紹介します。

Tailwind CSSとは何か

Tailwind CSSは、開発者にユーティリティクラスという強力な仕組みを提供します。あらかじめ定義されたCSSクラスの集合体であり、HTML上で直接あらゆるデザインを組み立てるための「部品」として機能します。HTML要素に1つ以上のクラスを付与するだけで、簡単にスタイリングできます。Tailwindは膨大な数のユーティリティを持つライブラリで、これらを組み合わせることで、自前でCSSを書くよりもはるかに速くカスタムデザインを作成できます。

例えば、おしゃれなヘッダー付きカードビューも、要素にいくつかのクラスを適用するだけで作れます。

<div class="text-center max-w-sm rounded overflow-hidden shadow-lg">
  <h1 class="text-3xl font-black">This is a styled header inside a styled card element.</h1>
</div>

たったこれだけです。クラスを自ら定義したり、CSSと格闘して思い通りの見た目を実現する苦労とは無縁になります。Tailwindには、一般的なスタイリングニーズをほぼカバーできるだけのユーティリティクラスがすでに用意されています。

ここ数年でTailwindは急速に普及しました。時間を節約しながら、一貫性のある洗練されたインターフェースを作れる点が評価されています。一方で、HTML内がクラスだらけになって煩雑になることを嫌う開発者もいるのが実情です。

新規RailsアプリへのTailwindセットアップ

わかりやすさのため、ゼロからRailsアプリケーションを新規作成するケースで説明します。本記事の例では以下のバージョンを使用します。

  • Rails 6.1
  • Ruby 3.0.0

rbenvはRubyの複数バージョンを管理するための標準的なツールです。Homebrewをお使いなら、brew install rbenvでインストールできます。

rbenvを使っている場合、rbenv install 3.0.0でRuby 3.0.0をインストールしましょう。

次に、rbenv local 3.0.0で現在のディレクトリのRubyバージョンを3.0.0に切り替えます。

新しいRubyバージョンの場合は、gem install railsでRailsをインストールしてください。

新しいRailsアプリケーションの作成

Rails 6.1とRuby 3.0の準備が整ったら、rails new tailwind-exampleを実行して新しいRailsアプリケーションを作成します。tailwind-exampleは任意のプロジェクト名に置き換えてください。ただし、以降のコードやコマンド中のプロジェクト名もすべて同じ名前に置き換える必要がある点に注意しましょう。

次に、作成したプロジェクトのディレクトリへ移動します。cd tailwind-example

最後に、rails serverでローカルサーバーを起動し、動作確認を行います。ブラウザでlocalhost:3000にアクセスすると、Railsのウェルカムページが表示されるはずです。問題なく表示されていれば準備完了です。

真っさらなRailsアプリが起動できたら、いよいよTailwindを追加して、より速いインターフェース開発を始めましょう。

Tailwind CSSのインストール

まず、以下のコマンドでTailwindCSSを依存関係として追加します。yarn add tailwindcss

次に、以下のコマンドでTailwindの設定ファイルを正しい場所に生成します。npx tailwindcss init

続いて、お好みのエディタ(VS Codeなど)でプロジェクトを開き、ルート直下にあるpostcss.config.jsを編集して、importsの一覧にrequire("tailwindcss"),を追記します。筆者のpostcssファイルは次のようになりました。

module.exports = {
  plugins: [
    require('postcss-import'),
    require('postcss-flexbugs-fixes'),
    require("tailwindcss"),
    require('postcss-preset-env')({
      autoprefixer: {
        flexbox: 'no-2009'
      },
      stage: 3
    })
  ]
}

次に、app/javascript配下にapplication.cssというファイルを作成します。このCSSファイルに以下のインポート文を記述します。

@import "tailwindcss/base";
@import "tailwindcss/utilities";
@import "tailwindcss/components";

さらに、app/javascript/packs/application.jsのimports一覧にimport "../application.css";を追加します。これによりTailwindのインポートがWebpacker経由で読み込まれるようになります。ファイルは以下のようになります。

// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so that it will be compiled.

import Rails from "@rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "@rails/activestorage"
import "channels"
import "../application.css";

Rails.start()
Turbolinks.start()
ActiveStorage.start()

アプリ全体でTailwindを使用するには、このwebpack参照をレイアウト側でも読み込む必要があります(app/views/layouts/application.html.erb)。

なお、TailwindはPostCSS 8を要求しますが、Rails 6はまだ対応していません。幸い公式ドキュメントに従えば、互換性のあるビルド版をインストールすることで簡単に解決できます。以下のコマンドを実行しましょう。

npm uninstall tailwindcss postcss autoprefixer
npm install -D tailwindcss@npm:@tailwindcss/postcss7-compat @tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9

動作確認をしてみよう

新しいCSSライブラリの威力を確かめるため、ビュー・コントローラー・モデルを一括生成してみましょう。Railsのスキャフォールドを使えば簡単です。rails generate scaffold User email:string password:string

次に、マイグレーションを実行してusersテーブルを作成します。rake db:migrate

これでUserモデルと、基本的なCRUD操作のためのビューおよびコントローラーアクションが揃いました。続いて、usersのindexページをアプリのルートとして設定しましょう。config/routes.rbroot 'users#index'を追加します。ルーティングファイルは以下のようになります。

Rails.application.routes.draw do
  root 'users#index'
  resources :users
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end

これでルートURLへのアクセスがすべてusersのindexページへ向かいます。rails serverでRailsサーバーを再起動し、localhost:3000にアクセスすると次のような画面が表示されるはずです。

しかしこの画面は2つの理由で今ひとつです。

  1. ユーザーデータが存在しない
  2. 見た目が地味である

1つ目の問題は、アプリケーションを実際に使ってみるだけで解決できます。indexページの「New User」リンクをクリックし、ダミーのパスワードでユーザーをいくつか登録しておきましょう。2つ目の問題はTailwindが解決してくれます。

それでは、Tailwind CSSが正しく設定されているかを確認するため、app/views/users/index.html.erbの先頭に以下のHTMLを追加してみます。

<div class="max-w-lg mx-auto mt-16 text-center max-w-sm rounded overflow-hidden shadow-lg p-10">
  <h1 class="mb-4 text-3xl font-black">Here are all our users!</h1>
  <p class="text-lg leading-snug">If this looks nice, it means Tailwind is set up properly.</p>
</div>

これはヘッダーと段落を含むシンプルなdiv要素で、それぞれにTailwind CSSでスタイルを当てています。ご覧のとおり、各要素に適切なクラスを追加するだけでスタイリングが完了します。設定が正しくできていれば、ユーザーページはきれいに表示されるはずです。

PurgeCSSでアセットサイズを削減する

Tailwind CSSのアセットは実は非常に巨大です。想像のとおり、大量のユーティリティクラス定義が積み重なるためです。そこで有効なのが、実際に使用しているクラス定義だけを残す仕組みです。幸い、Tailwind CSSにはそれを自動で行うpurge(パージ)機能が組み込まれています。何を残し何を削除するかを手動で選ぶ必要すらありません。

必要なのは、Tailwindの設定ファイルに対象パスを教えることだけです。そうすれば、未使用のCSSクラス定義を自動的にスキャンして取り除いてくれます。これにより、いつでも追加のユーティリティクラスを使える柔軟性を保ちながら、ファイルサイズとパフォーマンスの両面でアプリを最適化できます。

プロジェクトのルートにあるtailwind.config.jsを開いてください。初期状態は以下のようになっています。

module.exports = {
  purge: [],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}

便利なことに、Tailwind CSSクラスを使用している可能性のあるファイルのパスを指定するだけです。この例では.html.erbファイルでのみTailwindを使用したので、そのパスだけを指定します。ReactやVueなどヘビーなフロントエンドを併用している場合は、それらのパスも忘れずに追加してください。

設定ファイルにパスを追加すると、以下のようになります。

module.exports = {
  purge: [
    "./app/**/*.html.erb",
  ],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}

この設定により、NODE_ENVproductionの状態でコンパイルした際に、未使用のCSSクラスは除外されます。

Tailwind CSSクラスで作業時間を短縮する

Tailwind CSSの狙いは、より良く、より一貫性があり、より速いデザインを支援することです。ページのスタイリングは、適切なクラス名を追加するだけで完了します。公式ドキュメントに目を通すと全体像をつかめてとても役立ちますが、ここでは実際にユーザービューを装飾しながら、Tailwindがいかにスタイリングを簡単にするかを見ていきましょう。

ユーザーindexページのスタイリング

まずindexページでは、テーブル全体をdivで囲み、まとめてスタイルを適用できるようにします。このdivにはclass="p-10"(10pxのパディング)を付与します。また、ユーザー一覧のh1タグにもスタイリングを施します。以下の3つのクラスはほぼ見たままで意味が分かると思いますが、例えばmb-4は下部にマージンを4px追加するという意味です。変更後のUser Indexページのコードは次のようになります。

<div class="max-w-lg mx-auto mt-16 text-center max-w-sm rounded overflow-hidden shadow-lg p-10">
  <h1 class="mb-4 text-3xl font-black">Here are all our users!</h1>
  <p class="text-lg leading-snug">If this looks nice, it means Tailwind is set up properly.</p>
</div>

<div class="p-10">
  <h1 class="mb-4 text-4xl font-black">Users</h1>
  <table>
    <thead>
      <tr>
        <th>Email</th>
        <th>Password</th>
        <th colspan="3">Actions</th>
      </tr>
    </thead>

    <tbody>
      <% @users.each do |user| %>
        <tr>
          <td><%= user.email %></td>
          <td><%= user.password %></td>
          <td><%= link_to 'Show', user %></td>
          <td><%= link_to 'Edit', edit_user_path(user) %></td>
          <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
        </tr>
      <% end %>
    </tbody>
  </table>
  <br>
  <%= link_to 'New User', new_user_path %>
<div>

まだかなり素朴なので、もう少し磨きをかけましょう。テーブルとボタンにクラスを追加した結果がこちらです。

<div class="max-w-lg mx-auto mt-16 text-center max-w-sm rounded overflow-hidden shadow-lg p-10">
  <h1 class="mb-4 text-3xl font-black">Here are all our users!</h1>
  <p class="text-lg leading-snug">If this looks nice, it means Tailwind is set up properly.</p>
</div>

<div class="p-10">
  <h1 class="mb-4 text-4xl font-black">Users</h1>
  <table class="min-w-full table-auto">
    <thead class="bg-gray-800 text-gray-300" >
      <tr>
        <th>Email</th>
        <th>Password</th>
        <th colspan="3">Actions</th>
      </tr>
    </thead>

    <tbody>
      <% @users.each do |user| %>
        <tr class="border-4 border-gray-200">
          <td><%= user.email %></td>
          <td><%= user.password %></td>
          <td><%= link_to 'Show', user %></td>
          <td><%= link_to 'Edit', edit_user_path(user) %></td>
          <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
        </tr>
      <% end %>
    </tbody>
  </table>
  <br>
  <%= link_to 'New User', new_user_path, class: "bg-indigo-500 text-white px-4 py-2 border rounded-md hover:bg-white hover:border-indigo-500 hover:text-black" %>
<div>

これらの変更を加えると、ユーザーindexページはぐっと洗練された印象になります。

New Userページのスタイリング

せっかくなので、既存の「New User」ページも再スタイリングしてみましょう。現状はかなり無骨な見た目です。

まず、新規ユーザー用のビューに必要なクラスを適用します。筆者の場合は以下のように書きました。

<div class="bg-grey-lighter min-h-screen flex flex-col">
  <div class="container max-w-sm mx-auto flex-1 flex flex-col items-center justify-center px-2">
    <div class="bg-white px-6 py-8 rounded shadow-lg text-black w-full">
        <h1 class="mb-8 text-3xl text-center">Sign up</h1>
        <%= render 'form', user: @user %>

        <div class="text-center text-sm text-grey-dark mt-4">
            By signing up, you agree to the
            <a class="no-underline border-b border-grey-dark text-grey-dark" href="#">
                Terms of Service
            </a> and
            <a class="no-underline border-b border-grey-dark text-grey-dark" href="#">
                Privacy Policy
            </a>
        </div>
    </div>

    <div class="text-grey-dark mt-6">
      Already have an account?
      <%= link_to 'Sign In', '#', class: "no-underline border-b border-blue text-blue"%>
    </div>
  </div>
</div>

かなり良くなりましたが、フォーム本体にはまだスタイルが当たっていません!app/views/users/_form.html.erbにもいくつか編集が必要です。筆者の場合は次のようにしました。

<%= form_with(model: user) do |form| %>
  <% if user.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>

      <ul>
        <% user.errors.each do |error| %>
          <li><%= error.full_message %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.label :email %>
    <%= form.text_field :email, class: "block border border-grey-light w-full p-3 rounded mb-4"  %>
  </div>

  <div class="field">
    <%= form.label :password %>
    <%= form.text_field :password, class: "block border border-grey-light w-full p-3 rounded mb-4" %>
  </div>

    <%= form.submit "Sign Up", class: "w-full text-center py-3 rounded bg-indigo-600 text-white hover:bg-green-dark focus:outline-none" %>
<% end %>

編集箇所が多く、初出のクラスもいくつかありますが、必要な情報はすべて公式ドキュメントで確認できます。これらのクラスを適用すると、New Userページは格段に見栄えの良いものになります!

既存アプリへのTailwind追加

Tailwindを使いたいと思っている方の多くは、ゼロから始めるのではなく、すでにカスタムCSSやBootstrapなどの他のフレームワークを含む既存プロジェクトをお持ちでしょう。それでも全く問題ありません。

既存アプリがWebpakerで動作しているのであれば、「Tailwind CSSのインストール」で紹介した手順をそのまま踏襲できます。Webpackerが未導入の場合は、Gemfileに追加してbundle installを実行し、続けてbundle exec rails webpacker:installを行ったうえで、Tailwindのインストール手順に進んでください。

あとは、既存のCSSとTailwind CSSを自由に組み合わせて活用できます。

それでは、快適なスタイリングライフを楽しんでください!

  1. Rails × Hotwire入門:JavaScriptを書かずにSPAのような高速Webアプリを作る方法

    ページ遷移やフォーム送信を高速化したい、複雑なページをコンポーネント単位に分割したい——しかもJavaScriptのコードを一切書かずに。そんな願いを叶えてくれるのがHotwireです。本記事では、サーバーサイドレンダリングを実現するツール「Hotwire」を活用して、Railsアプリケーションを次のレベルへ引き上げる方法を、実例を交えながら詳しく解説します。 Hotwireとは? Hotwireは、JSONの代わりにHTMLを通信経路上でやり取りすることで、JavaScriptを書かずにモダンなWebアプリケーションを構築できるフレームワークです。HTMLベースの配信により、ページの表示

  2. Rails5でのAngularの使用

    あなたは前にその話を聞いたことがあります。分散型で完全に機能するバックエンドAPIと、通常のツールセットで作成されたフロントエンドで実行されているアプリケーションがすでにあります。 次に、Angularに移動します。または、AngularをRailsプロジェクトと統合する方法を探しているだけかもしれません。これは、この方法を好むためです。私たちはあなたを責めません。 このようなアプローチを使用すると、両方の世界を活用して、たとえばRailsとAngularのどちらの機能を使用してフォーマットするかを決定できます。 構築するもの 心配する必要はありません。このチュートリアルは、この目的のた