CRA (create-react-app) でTailwind CSSに入門してみます。
Tailwind CSS概要
一言でいえば、パラメータをカスタマイズ可能なCSSフレームワークという感じです。
Tailwind CSSの設定ファイル(tailwind.config.js
)に基づいてTailwind CSSがCSSファイルを生成してくれるので、それをTailwind CSSの規約通りのクラス名を通して利用する形になります。
- 自分でゼロからUIデザインする際に邪魔しないCSS設計
- Atomic Designをしたいし、自サイトのテイストを出したいが、そこそこCSSの定番は欲しいという要望にマッチしそう
- たとえば、UIライブラリとしてMaterial-UIがあるわけですが、マテリアルUI強制になってしまうのが欠点だったりする
- Atomic Designをしたいし、自サイトのテイストを出したいが、そこそこCSSの定番は欲しいという要望にマッチしそう
- 基本的にTailwind CSSが吐いたCSSを参照して利用する形となる。
- Tailwind CSSが定義するクラス名をかけばOK
- ある程度定番のスタイルは既存クラスを用いればいい
- flexボックスとか、死ぬほど書くスタイルはいちいちCSSで書きたくない
- 設定ファイルにより、カスタマイズ可能。レスポンシブの定義などを編集することができる
-
tailwind.config.js
により何ピクセルがどの画面サイズに該当するかなど編集可能。色やテーマも可能。 - 動的にパラメータを切り替えるサイトだと一工夫必要そう。
-
- PostCSSプラグインとして利用することができる
- 要するにCSSのマクロシステム(PostCSS)に組み込める
- 特にPostCSSがなくとも
tailwindcss build
コマンドで静的にTailwind CSSのクラス名が入ったCSSを出力可能。
- デフォルトのTailwind CSSでいいのであれば、CDN(
<link>
要素)で参照することも可能。<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
- ビルドする利点はカスタマイズしたりするところにある
環境準備
CRA (TypeScript) に組み込む前提で準備していきます。
$ yarn create react-app --template typescript tailwindcsstryout
$ cd tailwindcsstryout
$ yarn add tailwindcss
Tailwind CSSの初期設定ファイル (tailwind.config.js
) を生成します。
$ yarn tailwindcss init
Tailwind CSSの共通CSSファイル (src/tailwind.css
) を作成します。
@tailwind base;
@tailwind components;
@tailwind utilities;
package.json
に上記のTailwind CSSのマクロ入りのCSSをビルドするタスクを組み込みます。
(PostCSSのプラグインの構成でTailwind CSSを組み込むことができ、直接マクロ入りCSSをビルド工程でトランスパイルできるのであれば特にこういうビルドタスクは不要です。)
// preXXXX は XXXX の前に勝手に実行されるタスク
"prestart": "tailwindcss build src/tailwind.css -o src/tailwind.compiled.css",
"start": "react-scripts start",
"prebuild": "tailwindcss build src/tailwind.css -o src/tailwind.compiled.css",
"build": "react-scripts build",
上記のスクリプトによりCRAの起動時に勝手に src/tailwind.compiled.css
が作成されます。もちろん src/tailwind.css
を変更した場合はこの構成だと再起動が必要になります。
コンパイル済みのCSSをルートCSSから参照します。
@import "./tailwind.compiled.css";
これでアプリ内でTailwind CSSが定義するクラス名を利用することができるようになりました。
CRAでもリアルタイムでTailwind CSSを生成したい場合
純正のコマンドにはwatchオプションがないので、postcss-cliのwatchオプションを使う必要があります。 もちろんCRAじゃなく、普通にwebpack上でPostCSSを構成している人はそっちに組み込んだほうが快適だと思います。
$ yarn add -D postcss-cli
# ついでに npm-run-all も入れておく
$ yarn add -D npm-run-all
PostCSSの設定を行います。
module.exports = {
plugins: [
require("tailwindcss"),
// ベンダープレフィックス自動付与も欲しい人はautoprefixerを有効にすればOKです
// require("autoprefixer")
],
};
npm-scriptsの設定を変更します。
"start": "npm-run-all --parallel start:postcss start:cra",
"start:cra": "react-scripts start",
"start:postcss": "postcss src/tailwind.css -o src/tailwind.compiled.css -w",
"build": "npm-run-all build:postcss build:cra",
"build:cra": "react-scripts build",
"build:postcss": "postcss src/tailwind.css -o src/tailwind.compiled.css",
purge オプションでCSSを小さく
開発時に出力されるTailwind CSSのサイズがは9万行弱あるので、そのまま利用するのは厳しいです。もちろんminifyやgzip圧縮などは用いることになりますが、単純にソースコードに出てこないクラス名を削除する方法が用意されています。
たとえば、 src
フォルダ中のTypeScriptファイルに出てこないクラス名をすべて削除するのであれば、下記のようにすれば問題ありません。
purge: [
'./src/**/*.ts',
'./src/**/*.tsx',
]
上記を指定しつつ、 NODE_ENV=production
の状態でコンパイルすれば、ソースコードに出現しないクラス名はすべて削除されます。(クラス名関係なく要素に直接付与されるスタイルは残ります。)
$ NODE_ENV=production yarn build
基本的に適用されるスタイル
Preflightというものが基本的なスタイルとして用意されています。
@tailwind base;
normalize.cssをベースにしているらしいですが、基本的には下記のようなスタイルになるようです。
- いろんな要素の空白がゼロ
- 見出しは完全通常テキストと同様
- リストスタイル消去
-
img
,object
などメディア系のタグがブロック指定かつvertical-align: middle
- この動作が不要な時は
class="inline"
を指定
- この動作が不要な時は
- borderをすべて0幅、
solid
、テーマのデフォルト色に変更
preflightは下記を設定に入れれば無効にできるそうです。
corePlugins: {
preflight: false,
}
基本的な概念
クラス名
- 基本的にTailwind CSSのスタイリングは要素にクラス名を指定することで行われます。
- 要素に直接CSSが指定されている場合(例:前述のPreflight)もあります
ブレイクポイント
- レスポンシブデザインの見た目の切れ目になる画面横幅のこと
- デフォルトは、 sm: 640px 〜 md: 768px 〜 lg: 1024px 〜 xl: 1280px
- 特定画面幅の場合のみ有効にしたいスタイルがある場合は、
ブレイクポイント名:クラス名
のようにつければOK - デフォルト設定だと、 sm に適用されているものは、 md 以上でも適用されることに注意。
- この動作を変えたい場合は設定の変更が必要。
擬似クラス変種 (Pseudo Class Variants)
- たとえば、ホバー時だけにあてたいスタイルは
hover:クラス名
というように書くことができる - 上記のブレイクポイントとあわせて、
xl:hover:bg-blue-500
(画面サイズ特大時でホバーした時のみ青い背景をつける) という指定も可能。- ただ、もちろん上記のクラス名にあわせたCSSクラスの膨大な全組み合わせ定義をTailwind CSSが生成しなければならないので、デフォルトの設定では
hover
/focus
のみサポート。それ以外は設定を変えれば対応可能。
- ただ、もちろん上記のクラス名にあわせたCSSクラスの膨大な全組み合わせ定義をTailwind CSSが生成しなければならないので、デフォルトの設定では
関数・ディレクティブ
- Tailwind CSSでトランスパイルされるCSSファイル(本稿だと
src/tailwind.css
) ではいくつかディレクティブ(マクロ)を使えます -
@apply
-
@apply tailwindcssのクラス名1 tailwindcssのクラス名2 tailwindcssのクラス名3 ...
というようにCSSのスタイル指定部分に書くことによりスタイル指定をインライン化することができます - ブレイクポイントの指定や、擬似クラス変種のような条件指定はこれではできないことに注意。普通に擬似クラスを指定したり、
@screen
を使う必要がある。
-
-
@responsive
,@variants
-
@responsive { ... }
で囲ったCSS定義内のクラスについて、レスポンシブ分クラス名のコンビネーション(e.g..sm:myClassName
)を生成することができます -
@variants { ... }
も同じで疑似クラス分のコンビネーション(e.g..hover:myClassName
)を生成することができます
-
-
@screen
-
@screen sm { ... }
とすればsm
のレスポンシブ定義 (@media (min-width: 640px){ ... }
) で囲ったのと同じことにできます
-
-
theme(...)
関数- テーマとして設定ファイルで定義している変数の値にアクセスすることができます
emotion と同時利用する (twin.macro)
CSS-in-JS ライブラリと同時併用もできるのかやってみましょう。ここではCSS-in-JSライブラリとして emotion を用います。
$ yarn add @emotion/core @emotion/styled
くわえて、 styled-components に直接Tailwind CSSのクラス名を記述するために、twin.macro というものを使います。
$ yarn add twin.macro
あとは、 tw
マクロを使って直接Tailwind CSSのクラス名を書くことができます。
import styled from "@emotion/styled";
const Component = styled.div`
${tw`bg-blue-500`}
`
別件ですが、なんか tailwind.config.js
が src/
フォルダの中に無いと色々不具合が起こるらしいし、公式的なCRAのセットアップとしても src
に置いてほしいらしいので、これを行う際は src/tailwind.config.js
に設定ファイルを移すようにしたほうがいいかもしれません。
const tailwindcss = require("tailwindcss");
module.exports = {
plugins: [tailwindcss("src/tailwind.config.js")],
};
"babelMacros": {
"twin": {
"config": "src/tailwind.config.js"
}
},
まとめ
結構既存のスタイルを書きまくる作業などが軽減されそうな感じがします。
ただ、やっぱりCSS-in-JSと共存させるあたりは多少面倒で罠がありそうに感じました。
styled-component内に直接外部クラス名を書かせてくれれば特に問題ないんだけどなあ〜