前の記事では、Angular にシュッと tailwindcss を導入する 方法を紹介しました。今回は tailwindcss の設定ファイルに何が書いてあるのかを見ていきます。
記事執筆の環境は下記の通りです。
- @angular/cli v12.2
- node v16.8 (npm v7.21)
- tailwindcss v2.2
$ npx tailwindcss init
で生成される設定ファイルは tailwindcss のビルドのためのメタデータです。よく使うであろう項目がブランクで用意されていますが、それ以外にもいろいろな設定ができます。
// tailwind.config.js
module.exports = {
purge: [],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
}
この記事はとても長いので、項目ごとに個人的な重要度(★〜★★★)をつけてみました。また★ひとつの項目でも、重要な説明部分を太字にしています。ナナメ読みする時の参考にしてください。
時間が足りなくて Variant
Plugins
については言及していません...。
★ Prefix
tailwindcss では、用意されたユーティリティクラスを使用してスタイルをあてていきます。
<div class="bg-gray-100">...</div>
ユーティリティクラス名が自前の CSS クラスとコンフリクトするような場合、設定ファイルでプレフィクスを指定できます。
// tailwind.config.js
module.exports = {
prefix: "tw-",
};
プレフィクス指定後のユーティリティクラスの記述はこのように変わります。
<!-- 先頭に "tw-" を記述 -->
<div class="tw-bg-gray-100"></div>
★ Important
自前のスタイルと tailwindcss がコンフリクトする場合、自前のスタイル記述のほうが優先されます。
<!-- 青(tailwindcss) <<< 赤(自前のスタイル) -->
<div class="bg-blue-500 red">...</div>
<style>
.red { background: red; }
</style>
tailwindcss を優先したい場合には設定ファイルで important
を指定します。
// tailwind.config.js
module.exports = {
important: true
};
<!-- 青(tailwindcss) >>> 赤(自前のスタイル) -->
<div class="bg-blue-500 red">...</div>
<style>
.red { background: red; }
</style>
また設定ファイルの important
にセレクタを指定すると、そのセレクタのみで tailwindcss が優先されるようになります。
// tailwind.config.js
module.exports = {
important: "#container"
};
<div id="container">
<!-- #container では tailwindcss が優先される:青 -->
<div class="bg-blue-500 red">...</div>
</div>
<div>
<!-- #container の外では自前のスタイルが優先される:赤 -->
<div class="bg-blue-500 red">...</div>
</div>
<style>
.red { background: red; }
</style>
important に関わらずインライン CSS は常に最優先です。
<!-- 青(tailwindcss) <<< 赤(自前のスタイル) <<< 黄色(インライン) -->
<div
class="bg-blue-500 red"
style="background: yellow;"
>...</div>
★ Separator
tailwindcss では「マウスホバーした時に背景色を変更する」や「デバイスサイズに応じて背景色を変更する」というように変数のように値を変化させる仕組みを「バリアント」と呼びます。シンタックスは {バリアント}:{ユーティリティクラス名}
です。
<!-- マウスホバーした時に背景色を赤にする -->
<div class="bg-blue-500 hover:bg-blue-red">...</div>
HTML テンプレートライブラリなどの事情で CSS クラス名に :
を含める事ができない場合、設定ファイルでセパレータを変更する事ができます。
// tailwind.config.js
module.exports = {
// アンダースコア 2 個に変更する
separator: "__"
};
<!-- マウスホバーした時に背景色を赤にする -->
<div class="bg-blue-500 hover__bg-blue-red">...</div>
★ Variant Order
バリアントを複数指定した場合、first(先頭)
odd(出現順位が奇数)
のどちらにも該当する、という事が起こります。その場合はデフォルトの優先順位が適用されます。
<table>
<!-- first(先頭):グレー <<< odd(奇数):黄色 -->
<tr class="first:bg-gray-500 odd:bg-yellow-500">
<td></td>
</tr>
</table>
優先順位を変更するには、設定ファイルで variantOrder
を指定します。
// tailwind.config.js
module.exports = {
// 後ろのほうが優先順位が高い
variantOrder: ['odd', 'first'],
};
設定ファイルの変更によって odd
より first
が優先されるようになります。
<table>
<!-- first(先頭):グレー >>> odd(奇数):黄色 -->
<tr class="first:bg-gray-500 odd:bg-yellow-500">
<td></td>
</tr>
</table>
★★★ Jit
設定ファイルで JIT モードを有効にするといろいろな機能が使えるようになります。
// tailwind.config.js
module.exports = {
mode: 'jit',
};
※ 有効にしてもうまく動かない時は npm start
で起動しているビルトインサーバーを一旦止めて再度立ち上げ直してみてください。
16 進表記の色が指定できます。
<button class="text-[#bcbcbc]">...</button>
幅や高さなどのピクセル指定ができます。
<button class="w-[500px]">...</button>
calc()
が使えるようになります。
<div class="w-[calc(500px-4rem)]">...</div>
カスタムプロパティが使えるようになります。カスタムプロパティは単なる変数のため tailwindcss に色である事を伝えるには color:
バリアントと組み合わせて使います。
// src/styles.scss
:root {
--foo: hotpink;
--bar: skyblue;
}
<div class="bg-[color:var(--foo)] text-[color:var(--bar)]">...</div>
before::
after::
などの疑似要素を指定できます。
<!-- 前後に "*" を挿入する -->
<button class="before:content-['*']">...</button>
<button class="after:content-['*']">...</button>
:disabled
などの擬似クラスを指定できます。
<button class="
disabled:opacity-25
disabled:pointer-events-none
">...</button>
:invalid
:valid
などのバリデーションに関する擬似クラスを指定できます。
<!-- 値が入力されていなければ赤枠で表示する -->
<input
type="text"
required
class="border
invalid:border-red-500
valid:border-gray-300"
/>
<!-- 範囲外の値であれば赤枠で表示する -->
<input
type="number"
min="1"
max="3"
class="border
out-of-range:border-red-700
valid:border-gray-300"
/>
variant はつなげて複数書くと AND 条件になります。
<!-- focus(フォーカスされた)かつ odd(先頭要素)であれば背景を赤にする -->
<button class="focus:odd:bg-red-300">...</button>
ピンポイントで !important
指定ができます。
<button class="!font-medium">...</button>
/
に続けて不透明度の指定ができます。
<div class="bg-red-500/10">...</div> <!-- 背景を不透明度 10 にする -->
<div class="bg-red-500/20">...</div> <!-- 背景を不透明度 20 にする -->
<div class="bg-red-500/30">...</div> <!-- 背景を不透明度 30 にする -->
/[]
のようにすると不透明度を小数指定できます。
<div class="mt-4 bg-green-500/[.3]">...</div> <!-- 背景を不透明度 0.3 にする -->
<div class="mt-4 bg-green-500/[.4]">...</div> <!-- 背景を不透明度 0.4 にする -->
<div class="mt-4 bg-green-500/[.5]">...</div> <!-- 背景を不透明度 0.5 にする -->
線を上下左右で個別指定できます。
<button class="
border-4
border-l-blue-500
border-r-red-500
border-t-green-500
border-b-yellow-500
">...</button>
テキスト選択のハイライト色を指定できます。
<p class="selection:bg-blue-100">...</p>
リストマーカー(箇条書きの記号や数値の部分)の色を指定できます。
<ul class="list-decimal list-inside marker:text-red-500">
<li>ハム太郎</li> <!-- 1. ハム太郎 -->
<li>リボンちゃん</li> <!-- 2. リボンちゃん -->
</ul>
<!-- "1." "2." の部分が赤で表示される -->
キャレット(テキストカーソル)の色を指定できます。
<input type="text" class="caret-green-500">
peer
クラスを指定した要素の :checked
:focus
などの疑似クラスをキャッチして、別の要素の外観を変更する事ができます。
<ul>
<li>
<!-- チェックされた時 span の背景色が青になる -->
<input type="checkbox" class="peer" />
<span class="peer-checked:bg-blue-300">猿谷猿丸</span>
</li>
<li>
<!-- チェックされた時 span の背景色が緑になる -->
<input type="checkbox" class="peer" />
<span class="peer-checked:bg-green-300">紅蜂</span>
</li>
<li>
<!-- チェックされた時 span の背景色が赤になる -->
<input type="checkbox" class="peer" />
<span class="peer-checked:bg-red-300">ミスターX</span>
</li>
</ul>
★★ Dark Mode
media
設定ファイルで darkMode
を "media"
にセットすると OS の設定に応じてダークモード・ライトモードが切り替わるようになります。
// tailwind.config.js
module.exports = {
darkMode: 'media',
};
HTML では bg-white dark:bg-black
のように、dark:
バリアントありなしの 2 種類のユーティリティクラスを書いておきます。
<!-- src/app/app.component.html -->
<main class="bg-white dark:bg-gray-800">
<h1 class="text-gray-900 dark:text-white">Dark mode | Light mode</h1>
<p class="text-gray-600 dark:text-gray-300">
ダークモードはしっとりした色です
</p>
</main>
macOS ではシステム環境設定の「外観モード」で「ライト」または「ダーク」を切り替えます。
ダークモードでは dark:
バリアントのユーティリティクラスが使われます。
ライトモードでは dark:
バリアントなしのユーティリティクラスが使われます。
class
darkMode
には "class"
という値もセットできます。
こちらはコンテナの CSS クラスに応じてダークモード・ライトモードの切り替えを行うための機能です。"class"
を使うと、ユーザーがスライダなどを使って任意にダークモード・ライトモードをスイッチする事ができます。
// tailwind.config.js
module.exports = {
darkMode: 'class',
};
<!-- src/app/app.component.html -->
<!-- "dark" という CSS クラスを持ったコンテナ配下で "dark:" バリアントが有効になる -->
<main [class.dark]="enabled">
<div class="bg-white dark:bg-black">
<input type="checkbox" [(ngModel)]="enabled" /> 🌛 | 🌞
<p class="text-black dark:text-white">Dark mode | Light mode</p>
</div>
</main>
★★★ Purge
tailwindcss では未使用のユーティリティクラスは「パージ」という仕組みによってビルドから除外されます。
tailwindcss は Node がプロダクションモードの時にパージを実行します。Angular のビルドはプロダクションモードとは関連しないので tailwindcss の環境変数などを使って enabled
を切り替える必要があります。
// tailwind.config.js
module.exports = {
purge: {
// `npm run build` が実行された時 tailwindcss の環境変数が変わるのでそれを利用する
enabled: process.env.TAILWIND_MODE === 'build',
content: [...],
},
enabled
でオンオフを切り替える事もできます。
// tailwind.config.js
module.exports = {
purge: {
// プロダクションモードでなくても毎回パージを実行する
// `npm start` でもパージが走る
// 未使用のユーティリティクラスはブラウザの開発者ツールでサジェストされなくなる
enabled: true,
content: [...],
},
ユーティリティクラスが未使用かどうかは purge > content
に該当するファイルの中にクラスの記述が存在するかどうかで決まります。
// tailwind.config.js
module.exports = {
purge: {
content: [
'./src/**/*.{html,ts}',
'./src/**/*.js',
],
},
ユーティリティクラスの存在は単純な正規表現を使って探索されます。
/[^<>"'`\s]*[^<>"'`\s:]/g
そのため .js
に書いた変数の値もヒットします。
// src/foo.js
const className = "text-gray-100";
文字列を連結してユーティリティクラスを組み立てているような場合は、正規表現にヒットしないためビルド済みファイルに出力されません。
// src/foo.js
const className1 = "text-" + "gray-200"; // 出力されない
const className2 = `bg-${color}-red`; // 出力されない
★ Safelist
ビルド済みの CSS を Angular 外から参照する場合は、safelist
を使う事でパージ対象外のユーティリティクラスを指定する事ができます。
// tailwind.config.js
module.exports = {
mode: 'jit',
purge: {
content: ['src/**/*.{html,ts}'],
safelist: [
// このクラスは未使用であってもパージしない
'bg-blue-300'
],
},
npm run build
/* styles.{hash}.css */
.bg-blue-300{--tw-bg-opacity:1;background-color:rgba(147,197,253,var(--tw-bg-opacity))}
★ Core Plugins
使用しない CSS は corePlugins
で false を設定します。
// tailwind.config.js
module.exports = {
corePlugins: {
backgroundColor: false,
display: false,
},
};
このようにすると background-color
と display
を変更するユーティリティクラスはビルド済みファイルに含まれなくなります。そのため bg-yellow-500
inline
は見た目上の意味をなさなくなります。
<!-- ユーティリティクラスを指定しても見た目が何も変わらない -->
<div class="bg-yellow-500 inline"></div>
★ Core Plugins > preflight
tailwindcss ではユーティリティクラスでスタイルをあてる前準備として、ブラウザのデフォルトのスタイルを打ち消すノーマライズの処理を行っています。いわゆる「CSS リセット」ですが tailwindcss ではこれを「プリフライト」と呼びます。
tailwindcss をシュッと導入した Angular では styles.scss
に base
というインポート文があるはずです。この部分が「プリフライト」です。
// styles.scss
@import 'tailwindcss/base'; // <=== プリフライト
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
プリフライトの CSS の中身は GitHub で見る事ができます。
ユーティリティクラスを何も指定しないと、プリフライトされただけの状態になります。ブラウザのデフォルトのスタイルは打ち消されているため、枠線も背景色も何も表示されません。
<!-- 枠線も背景色もないボタン -->
<button class="">...</button>
プリフライトが困るという場合は preflight
で無効にできます。
module.exports = {
corePlugins: {
preflight: false,
},
特に理由がない限りデフォルトのまま有効にしておいたほうが良いでしょう。プリフライトは、ブラウザ間のレンダリングの差異をリセットしてユーティリティクラスをスムーズに適用するためのものだからです。
おわりに
tailwindcss がなんとなく凄そうって雰囲気が伝わりましたでしょうか。これだけ設定ファイルをいじくりまわす事はそうそうないと思いますが、この記事を「そういえばあんな事ができたっけ...」とチャッと開ける引き出しとして使っていただけたらと思います。
次の記事では tailwindcss のカスタマイズについて紹介します。
Angular 12 にシュッと導入してチャッと理解した tailwindcss をピャッとカスタマイズする