Tailwind CSS の一歩進んだ書き方
Changelog
2025.02.02
- v4.0 対応のための加筆修正
- 解説順の変更
以下差分:
-## Just-in-Time 改め arbitrary values
+## Just-in-Time 改め arbitrary values (任意の値)
-上記例にある `text-3xl` などのスタイルは予め Tailwind CSS が用意しているものですが、`tailwind.config.js` を編集することで簡単に変更・追加できます。ただし、1 回しか使わないスタイルでもいちいち `tailwind.config.js` に登録しないといけないので、その不便さを解消する機能として v2.1 から Just-in-Time (JIT) モードが導入されました。
+上記例にある `text-3xl` などのスタイルは予め Tailwind CSS が用意しているものですが、v3.4 までは `tailwind.config.js`、v4.0 からは CSS ファイルで `@theme` を利用して、簡単に変更・追加・削除できます。ただし、1 回しか使わないスタイルでもいちいち登録しないといけないのは不便なので、それを解消する機能として v2.1 から Just-in-Time (JIT) モードが導入されました。
-v3.0 からは JIT がデフォルトになりましたので、わざわざ「JIT モード」ということもなくなり、ドキュメントではその機能を単に arbitrary values (任意値) と記述しています。
+v3.0 からは JIT がデフォルトになりましたので、わざわざ「JIT モード」ということもなくなり、ドキュメントでは arbitrary values (任意の値) と呼ばれるようになりました。その後、値に加えてプロパティやバリアントでも利用できるようになりました。
## シンプルな任意値
```html:html
<h1 class="text-[10vw]">
Hello world!
</h1>
```
+
+### ダイナミックユーティリティ
+
+```html:html
+<h1 class="mb-3.75">
+ Hello world!
+</h1>
+```
+
+v4.0 から導入された機能。これまで上記は `spacings` に `3.75` を設定する必要がありましたが、任意値を使わなくても、いくつかのプロパティは動的にユーティリティを生成するようになりました。
+
+```html:html
+<h1 class="mb-[--spacing(3.6)]">
+ Hello world!
+</h1>
+```
+
+ただし、`m-*` `w-*` など、`--spacing` を使うユーティリティは `0.25` 刻みである必要があります。`3.6` を指定したい場合は `mb-[0.9rem]` のように具体的な値を書くか、上記の `--spacing()` 関数を利用できます。
-## マイナス値は角括弧内で
+## マイナス値も同様に書ける
```html:html
-<h1 class="ml-[-1em]">
+<h1 class="-ml-[1em]">
Hello world!
</h1>
```
-通常では `-ml-1` のように先頭に `-` をつけますが、任意値は `[]` の中に記述します。
+`-ml-1` と同様、先頭に `-` をつけることで任意の値もマイナス値にできます。以前は `ml-[-1em]` のように記述する必要がありました。
## CSS カスタムプロパティの利用
+
+### v4.0 以上
+
+```html:html
+<h1 class="px-(--gutter)">
+ Hello world!
+</h1>
+```
+
+### v3.x
```html:html
<h1 class="px-[--gutter]">
Hello world!
</h1>
```
-`px-[var(--gutter)]` のように記述することもできますが、`var()` は省略可能です。
+v3.4 までは `[]` で `var()` を省略できましたが、v4.0 からは `()` を使う必要があります。`var()` を省略せずに `px-[var(--gutter)]` のように記述すれば、v4.0 以上・v3.4 以下のどちらにも対応できます。
## データ型の明示
```html:html
-<h1 class="text-[length:--title-size] text-[color:--title-color]">
+<h1 class="text-(--title-color) text-(length:--title-size) bg-[length:1em_1em]">
Hello world!
</h1>
```
-`text-` のように、色やサイズの複数プロパティが一つの名前を共有しているケースがあります。`text-[22px] text-[#bada55]` を記述すると、サイズなのか色なのかは、値から自動的に判別されます。しかし、CSS カスタムプロパティなど、値から判別できない場合があります。このようなときは `length:` や `color:` などで明示することができます。CSS カスタムプロパティ以外でも、たとえば `background-size` は `bg-[length:200px_100px]` のようにデータ型を明示する必要があったりします。
+`text-*` や `bg-*` のように、色やサイズなど複数のプロパティが一つの名前を共有しているケースがあります。`text-[#bada55] text-[22px]` を記述すると、サイズなのか色なのかは、値から自動的に判別されます。しかし、CSS カスタムプロパティなど、値から判別できない場合があります。このようなときは `length:` や `color:` などでデータ型を明示する必要があります。なお、`text` や `bg` はデータ型の指定がなければ `color` として認識します。
+
+CSS カスタムプロパティ以外でも、たとえば `background-size` は `bg-[length:1em_1em]` のようにデータ型を明示する必要があったりします。
+
+データ型の一覧はドキュメントに載っていないと思いますので、[ソースコード](https://github.com/tailwindlabs/tailwindcss/blob/50bafce75623a5a5b7171ef278b445c437c6be48/packages/tailwindcss/src/utils/infer-data-type.ts#L5)を読む必要があります。以下に掲載しておきます。
+
+`color` `length` `percentage` `ratio` `number` `integer` `url` `position` `bg-size` `line-width` `image` `family-name` `generic-name` `absolute-size` `relative-size` `angle` `vector`
## 色の透明度は `/` で指定可能
```html:html
<h1 class="text-black/75 bg-red-500/[0.15]">
Hello world!
</h1>
```
任意値も使用可能です。
+
+```html:html
+<h1 class="bg-(--custom-color)/25">
+ Hello world!
+</h1>
+```
+
+v4.0 以上では、カスタムプロパティに対しても使用できます。
-## `::before` `::after` などの疑似要素・擬似クラス
+## 疑似要素・擬似クラス
+
+### `::before` `::after`
```html:html
<h1 class="after:content-['👋🏼']">
Hello world!
</h1>
```
+### `:has()`
+
+```html:html
+<h1 class="has-[+p]:mb-0">
+ Hello world!
+</h1>
+<p>Scelerisque at velit rutrum augue molestie ante.</p>
+```
+
+`h1` にデフォルトでマージが設定されているとして、直後に `p` がある場合のみ `margin-bottom` をなくします。`has-only` のようにあらかじめ用意されているものもいくつかあります。
+
+### `:not()`
+
+```html:html
+<ul>
+ <li class="not-last:border-b">1st</li>
+ <li class="not-last:border-b">2nd</li>
+ <li class="not-last:border-b">3rd</li>
+</ul>
+```
+
+`li` がプログラムでループ出力されるとして、最後の要素ではない場合下にボーダーをつけます。もちろん `has-*` 同様 `not-[*]` で任意の値も取れます。
+
-`::before` `::after` 以外にもさまざまな疑似要素・擬似クラスが用意されています。こちらの[一覧表](https://tailwindcss.com/docs/hover-focus-and-other-states#quick-reference)をご覧ください。
+上記以外にもさまざまな疑似要素・擬似クラスが用意されています。こちらの[一覧表](https://tailwindcss.com/docs/hover-focus-and-other-states#quick-reference)をご覧ください。
-## `data` 属性
+## HTML 属性
+
+### データ属性
```html:html
-<h1 class="text-2xl data-[size=large]:text-3xl">
+<h1 class="text-2xl data-[size=large]:text-3xl" data-size="large">
Hello world!
</h1>
```
通常は `text-2xl` ですが、`data-size="large"` がある場合は `text-3xl` になります。
+
+### ARIA
+
+```html:html
+<p class="aria-hidden:opacity-0" aria-hidden="true">
+ Hello world!
+</p>
+```
+
+`aria-hidden="true"` のとき視覚的にも見えなくなり、ARIA 属性の制御だけで表示もコントロールできるようになります。
+
+疑似要素・擬似クラス同様、その他属性も同じ[一覧表](https://tailwindcss.com/docs/hover-focus-and-other-states#quick-reference)にまとめられています。
+## コンテナクエリ
+
+```html:html
+<div class="@container">
+ <h1 class="text-4xl @md:text-5xl">
+ Hello world!
+ </h1>
+</div>
+```
+
+これまでプラグインを利用する必要がありましたが、v4.0 からはコアに取り込まれました。メディアクエリとコンテナクエリのブレークポイントの値は同じではないことに注意が必要です。たとえば、`md` は `48rem` ですが、`@md` は `28rem` です。
## 祖先要素の状態によるスタイリング
+
+### `group-*`
```html:html
<a href="https://example.com" class="group">
<h2 class="group-hover:underline">Hello world!</h2>
<p>Etiam facilisi eu dolor per leo ante…</p>
</a>
```
祖先要素に `group` をつけて、子孫要素に `group-*` でスタイリングすることができます。マウスホバーでよく使うと思いますが、ほかにも `group-odd` などほとんどの擬似クラスと組み合わせられます。
+
+### `in-*`
+
+```html:html
+<div tabindex="0">
+ <p class="opacity-50 in-focus:opacity-100">
+ Curabitur praesent molestie iaculis elementum vulputate orci.
+ </p>
+</div>
+```
+
+v4.0 から導入された `in-*` を使えば、祖先要素に特定のクラスを追加することなく、祖先要素の状態によって子孫要素をスタイリングできます。
+
+ただし、`in-*` はすべての祖先要素に反応するので、たとえば `in-hover:` だと、`body` にも反応してしまいます。なので基本的には `group-*` のほうが有用かと思いますが、後述[特定の要素内でスタイルを変える](#%E7%89%B9%E5%AE%9A%E3%81%AE%E8%A6%81%E7%B4%A0%E5%86%85%E3%81%A7%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%82%92%E5%A4%89%E3%81%88%E3%82%8B)方法としては便利かもしれません。
## 特定の要素内でスタイルを変える
```html:html
<body class="home">
<h1 class="text-black [body.home_&]:text-red-500">
Hello world!
</h1>
</body>
```
基本は黒ですが、`home` ページでだけ赤になります。
```html:html
<body class="group home">
<h1 class="text-black group-[.home]:text-red-500">
Hello world!
</h1>
</body>
```
v3.2 で追加されたダイナミック `group-*` でも書けます。
+
+```html:html
+<body class="home">
+ <h1 class="text-black in-[body.home]:text-red-500">
+ Hello world!
+ </h1>
+</body>
+```
+
+v4.0 で追加された `in-*` を使えば、`body` に `group` を追加する必要がなくなります。
## ダイナミックブレークポイント
```html:html
<h1 class="text-7xl min-[1440px]:text-[5vw]">
Hello world!
</h1>
```
-特殊なブレークポイントのために、いちいち `screens` に設定を追加する必要がなくなります。
+特殊なブレークポイントのために、いちいち設定を追加する必要がなくなります。
## CSS ファイル内で Tailwind CSS で設定されている値を使う
+### レガシー
+
```css:css
h1 {
font-size: min(5vw, theme(fontSize.7xl));
}
```
CSS ファイル内での基本的なスタイリングは `@apply text-7xl;` のように記述できますが、関数などで値のみを利用したい場合は `theme()` 関数で実現できます。`theme()` 関数の引数は `tailwind.config.js` の `theme` や `extend` のプロパティに対応しています。
+v4.0 以上でも利用できますが非推奨になりましたので代わりに以下の方法を利用してください。
+
+### v4.0 以上
+
+```css:css
+h1 {
+ font-size: min(5vw, var(--text-7xl));
+}
+```
+
+v4.0 から設定値はすべて CSS カスタムプロパティとして `:root` に出力されるのでそのまま利用できます。
## 任意値内で Tailwind CSS で設定されている値を使う
+### レガシー
+
```html:html
<h1 class="text-[min(5vw,theme(fontSize.7xl))]">
Hello world!
</h1>
```
-CSS ファイル同様、任意値内でも `theme()` 関数を利用することで Tailwind CSS テーマの設定値を使うことができます。
+CSS ファイル同様、任意値内でも `theme()` 関数を利用することで Tailwind CSS テーマの設定値を使うことができます。こちらも 4.0 以上でも利用できますが非推奨だと思います。
+
+### v4.0 以上
+
+```html:html
+<h1 class="text-[min(5vw,var(--text-7xl))]">
+ Hello world!
+</h1>
+```
+
+こちらも CSS ファイル内と同様、CSS カスタムプロパティをそのまま利用できます。
-## `theme()` 関数での色の透明度も `/` で指定可能
+## `--alpha()` 関数で色の透明度を変更
+
+```css:css
+h1 {
+ background: --alpha(var(--color-red-500) / 25%);
+}
+```
+
+v4.0 から導入された機能。任意値でも利用できますが、その場合は [`/` を利用したほう](#%E8%89%B2%E3%81%AE%E9%80%8F%E6%98%8E%E5%BA%A6%E3%81%AF-%2F-%E3%81%A7%E6%8C%87%E5%AE%9A%E5%8F%AF%E8%83%BD)がいいと思います。
```css:css
h1 {
background: theme(colors.red.500 / 25%);
}
```
+v3.x でも `theme()` 関数を利用すればテーマで設定された色の透明度を変更できます。
+
```html:html
<h1 class="bg-[theme(colors.red.500/25%))]">
Hello world!
</h1>
```
-CSS ファイルでも任意値でも利用可能。
+任意値でも利用可能。
# おわりに
-以上の記述方法を活用すれば、特殊なケースでも CSS を個別に書いたり、`tailwind.config.js` をカスタマイズしたりする必要がほぼなくなります。開発速度が上がるうえ、メンテナンスコストも減るのでぜひご活用ください。
+以上の記述方法を活用すれば、特殊なケースでも CSS を個別に書いたり、`@theme` や `tailwind.config.js` でカスタマイズしたりする必要性を減らせます。開発速度が上がるうえ、メンテナンスコストも減るのでぜひご活用ください。
2023.12.25
- v3.3、v3.4 の機能を追加
-
theme()
関数の追加 - 解説順の変更
以下差分:
-## CSS カスタムプロパティ
+## CSS カスタムプロパティの宣言
+## CSS カスタムプロパティの利用
+
+```html:html
+<h1 class="px-[--gutter]">
+ Hello world!
+</h1>
+```
+
+`px-[var(--gutter)]` のように記述することもできますが、`var()` は省略可能です。
-<h1 class="text-[length:var(--title-size)] text-[color:var(--title-color)]">
+<h1 class="text-[length:--title-size] text-[color:--title-color]">
+## フォントサイズと一緒に行の高さを指定するショートハンド
+
+```html:html
+<h1 class="text-5xl/tight">
+ Hello world!
+</h1>
+```
+
+もちろん `text-5xl leading-tight` のように別々でも記述できますが、`/` を使えば短く書けます。
+
+```html:html
+<h1 class="text-5xl/[4rem]">
+ Hello world!
+</h1>
+```
+
+任意値も使えます。
+## グラデーションの位置調整
+
+```html:html
+<h1 class="bg-gradient-to-r from-indigo-500 from-10% via-purple-500 via-[31.56%] to-pink-500 to-90%">
+ Hello world!
+</h1>
+```
+
+`from` `via` `to` でグラデーションの位置を調整できます。任意の値を使うことも可能。
+
## 子要素を一括指定
+```html:html
+<dl class="[&>dt]:font-bold">
+ <dt>Foo</dt>
+ <dd>Semper cursus dictumst.</dd>
+ <dt>Bar</dt>
+ <dd>Dapibus rhoncus nec.</dd>
+</dl>
+```
+
+上記は特定の子要素を指定する方法ですが、すべての子要素の場合は下記のように `*` を使って短く書けます。`li` などのスタイリングで便利です。
```html:html
-<ul class="[&>li]:border-b">
+<ul class="*:border-b">
<li>1st</li>
<li>2nd</li>
<li>3rd</li>
</ul>
```
+上記は `[&>*]:border-b` に相当します。
+## CSS ファイル内で Tailwind CSS で設定されている値を使う
+
+```css:css
+h1 {
+ font-size: min(5vw, theme(fontSize.7xl));
+}
+```
+
+CSS ファイル内での基本的なスタイリングは `@apply text-7xl;` のように記述できますが、関数などで値のみを利用したい場合は `theme()` 関数で実現できます。`theme()` 関数の引数は `tailwind.config.js` の `theme` や `extend` のプロパティに対応しています。
+
+## 任意値内で Tailwind CSS で設定されている値を使う
+
+```html:html
+<h1 class="text-[min(5vw,theme(fontSize.7xl))]">
+ Hello world!
+</h1>
+```
+
+CSS ファイル同様、任意値内でも `theme()` 関数を利用することで Tailwind CSS テーマの設定値を使うことができます。
+
+## `theme()` 関数での色の透明度も `/` で指定可能
+
+```css:css
+h1 {
+ background: theme(colors.red.500 / 25%);
+}
+```
+
+```html:html
+<h1 class="bg-[theme(colors.red.500/25%))]">
+ Hello world!
+</h1>
+```
+
+CSS ファイルでも任意値でも利用可能。
2023.02.24
- v3.2 の機能を追加
以下差分:
+## `data` 属性
+
+```html:html
+<h1 class="text-2xl data-[size=large]:text-3xl">
+ Hello world!
+</h1>
+```
+
+通常は `text-2xl` ですが、`data-size="large"` がある場合は `text-3xl` になります。
+## ネストされた祖先要素の状態によるスタイリング
+
+```html:html
+<div class="group">
+ <a href="https://example.com/">Hello world!</a>
+ <div class="invisible group-hover:visible group/child">
+ <a href="https://example.com/child/">Child</a>
+ <div class="invisible group-hover/child:visible">
+ <a href="https://example.com/child/grandchild/">Grandchild</a>
+ </div>
+ </div>
+</div>
+```
+
+たとえば、マウスホバーしたときに下層メニューを表示するようなネストされたナビゲーションでは、`group` だけだと最下層のメニューまで表示されてしまいます。`group/*` のようにそれぞれのグループに名前をつけることでこの問題を解決できます。スタイリングしたい要素には `group-hover/*` のようなバリアントをつけます。
-
-:::message alert
-以下 v3.1 で実装される予定の variant にも任意値ですが、`tailwindcss@insiders` をインストールすることでテスト可能です。
-:::
-
+```html:html
+<body class="group home">
+ <h1 class="text-black group-[.home]:text-red-500">
+ Hello world!
+ </h1>
+</body>
+```
+
+v3.2 で追加されたダイナミック `group-*` でも書けます。
+## メディアクエリの `max-width`
+
+```html:html
+<h2 class="sr-only lg:not-sr-only">
+ Menu
+</h2>
+```
+
+Tailwind CSS では通常メディアクエリは `min-width` を使ったモバイルファーストになっているので、上記のようにモバイルでは非表示にしたい場合、デスクトップでスタイルを戻す必要がありました。
+
+```html:html
+<h2 class="max-lg:sr-only">
+ Menu
+</h2>
+```
+
+`max-*` バリアントを使えば元に戻すという手間が不要になります。プロパティが複数ある場合はかなりわかりやすく書けるようになります。
+
+## ダイナミックブレークポイント
+
+```html:html
+<h1 class="text-7xl min-[1440px]:text-[5vw]">
+ Hello world!
+</h1>
+```
+
+特殊なブレークポイントのために、いちいち `screens` に設定を追加する必要がなくなります。
はじめに
「Tailwind CSS とは何か」については理解している前提で進めます。
<h1 class="text-3xl font-bold underline">
Hello world!
</h1>
簡単な例として、上記 HTML を記述すると、以下のようにスタイリングされます。
Just-in-Time 改め arbitrary values (任意の値)
上記例にある text-3xl
などのスタイルは予め Tailwind CSS が用意しているものですが、v3.4 までは tailwind.config.js
、v4.0 からは CSS ファイルで @theme
を利用して、簡単に変更・追加・削除できます。ただし、1 回しか使わないスタイルでもいちいち登録しないといけないのは不便なので、それを解消する機能として v2.1 から Just-in-Time (JIT) モードが導入されました。
v3.0 からは JIT がデフォルトになりましたので、わざわざ「JIT モード」ということもなくなり、ドキュメントでは arbitrary values (任意の値) と呼ばれるようになりました。その後、値に加えてプロパティやバリアントでも利用できるようになりました。
<h1 class="text-[10vw] font-bold underline">
Hello world!
</h1>
text-[10vw]
のように記述することで、登録されていないスタイルでも以下の CSS が自動的に生成されます。
.text-\[10vw\] {
font-size: 10vw;
}
一歩進んだ記述方法まとめ
しかし、自由度が増したことで記述方法が複雑になってきましたので、それらをまとめていきます。
シンプルな任意値
<h1 class="text-[10vw]">
Hello world!
</h1>
ダイナミックユーティリティ
<h1 class="mb-3.75">
Hello world!
</h1>
v4.0 から導入された機能。これまで上記は spacings
に 3.75
を設定する必要がありましたが、任意値を使わなくても、いくつかのプロパティは動的にユーティリティを生成するようになりました。
<h1 class="mb-[--spacing(3.6)]">
Hello world!
</h1>
ただし、m-*
w-*
など、--spacing
を使うユーティリティは 0.25
刻みである必要があります。3.6
を指定したい場合は mb-[0.9rem]
のように具体的な値を書くか、上記の --spacing()
関数を利用できます。
マイナス値も同様に書ける
<h1 class="-ml-[1em]">
Hello world!
</h1>
-ml-1
と同様、先頭に -
をつけることで任意の値もマイナス値にできます。以前は ml-[-1em]
のように記述する必要がありました。
calc()
clamp()
などを使う場合はスペースをつめる
値に <h1 class="text-[clamp(32px,2.5vw+24px,48px)]">
Hello world!
</h1>
_
を使う
スペースが必要な値は代わりに <h1 class="drop-shadow-[0_0_1em_#0ff]">
Hello world!
</h1>
任意プロパティ
<h1 class="animate-bounce [animation-delay:3s]">
Hello world!
</h1>
用意されていないプロパティは上記の [animation-delay:3s]
のように書けます。アニメーションの細かい調整も可能になります。
CSS カスタムプロパティの宣言
<h1 class="[--viewport-from:320] [--viewport-to:960] [--min-font-size:32] [--max-font-size:48]">
Hello world!
</h1>
以前投稿した「CSS カスタムプロパティによる流動的フォントサイズ」のように、要素に CSS カスタムプロパティを設定することでスタイリングするようなケースで重宝されます。
CSS カスタムプロパティの利用
v4.0 以上
<h1 class="px-(--gutter)">
Hello world!
</h1>
v3.x
<h1 class="px-[--gutter]">
Hello world!
</h1>
v3.4 までは []
で var()
を省略できましたが、v4.0 からは ()
を使う必要があります。var()
を省略せずに px-[var(--gutter)]
のように記述すれば、v4.0 以上・v3.4 以下のどちらにも対応できます。
データ型の明示
<h1 class="text-(--title-color) text-(length:--title-size) bg-[length:1em_1em]">
Hello world!
</h1>
text-*
や bg-*
のように、色やサイズなど複数のプロパティが一つの名前を共有しているケースがあります。text-[#bada55] text-[22px]
を記述すると、サイズなのか色なのかは、値から自動的に判別されます。しかし、CSS カスタムプロパティなど、値から判別できない場合があります。このようなときは length:
や color:
などでデータ型を明示する必要があります。なお、text
や bg
はデータ型の指定がなければ color
として認識します。
CSS カスタムプロパティ以外でも、たとえば background-size
は bg-[length:1em_1em]
のようにデータ型を明示する必要があったりします。
データ型の一覧はドキュメントに載っていないと思いますので、ソースコードを読む必要があります。以下に掲載しておきます。
color
length
percentage
ratio
number
integer
url
position
bg-size
line-width
image
family-name
generic-name
absolute-size
relative-size
angle
vector
font-size
と一緒に line-height
を指定するショートハンド
<h1 class="text-5xl/tight">
Hello world!
</h1>
もちろん text-5xl leading-tight
のように別々でも記述できますが、/
を使えば短く書けます。
<h1 class="text-5xl/[4rem]">
Hello world!
</h1>
任意値も使えます。
/
で指定可能
色の透明度は <h1 class="text-black/75 bg-red-500/[0.15]">
Hello world!
</h1>
任意値も使用可能です。
<h1 class="bg-(--custom-color)/25">
Hello world!
</h1>
v4.0 以上では、カスタムプロパティに対しても使用できます。
グラデーションの位置調整
<h1 class="bg-gradient-to-r from-indigo-500 from-10% via-purple-500 via-[31.56%] to-pink-500 to-90%">
Hello world!
</h1>
from
via
to
でグラデーションの位置を調整できます。任意の値を使うことも可能。
!
で !important
<h1 class="!font-normal">
Hello world!
</h1>
!
をつけることで !important
にすることができます。Tailwind CSS メインのプロジェクトではほとんど使うことはないと思いますが、保守案件など途中から Tailwind CSS を導入した場合は重宝すると思います。ほかへの影響もほぼないのでわりとカジュアルに使えます。
疑似要素・擬似クラス
::before
::after
<h1 class="after:content-['👋🏼']">
Hello world!
</h1>
:has()
<h1 class="has-[+p]:mb-0">
Hello world!
</h1>
<p>Scelerisque at velit rutrum augue molestie ante.</p>
h1
にデフォルトでマージが設定されているとして、直後に p
がある場合のみ margin-bottom
をなくします。has-only
のようにあらかじめ用意されているものもいくつかあります。
:not()
<ul>
<li class="not-last:border-b">1st</li>
<li class="not-last:border-b">2nd</li>
<li class="not-last:border-b">3rd</li>
</ul>
li
がプログラムでループ出力されるとして、最後の要素ではない場合下にボーダーをつけます。もちろん has-*
同様 not-[*]
で任意の値も取れます。
上記以外にもさまざまな疑似要素・擬似クラスが用意されています。こちらの一覧表をご覧ください。
HTML 属性
データ属性
<h1 class="text-2xl data-[size=large]:text-3xl" data-size="large">
Hello world!
</h1>
通常は text-2xl
ですが、data-size="large"
がある場合は text-3xl
になります。
ARIA
<p class="aria-hidden:opacity-0" aria-hidden="true">
Hello world!
</p>
aria-hidden="true"
のとき視覚的にも見えなくなり、ARIA 属性の制御だけで表示もコントロールできるようになります。
疑似要素・擬似クラス同様、その他属性も同じ一覧表にまとめられています。
コンテナクエリ
<div class="@container">
<h1 class="text-4xl @md:text-5xl">
Hello world!
</h1>
</div>
これまでプラグインを利用する必要がありましたが、v4.0 からはコアに取り込まれました。メディアクエリとコンテナクエリのブレークポイントの値は同じではないことに注意が必要です。たとえば、md
は 48rem
ですが、@md
は 28rem
です。
祖先要素の状態によるスタイリング
group-*
<a href="https://example.com" class="group">
<h2 class="group-hover:underline">Hello world!</h2>
<p>Etiam facilisi eu dolor per leo ante…</p>
</a>
祖先要素に group
をつけて、子孫要素に group-*
でスタイリングすることができます。マウスホバーでよく使うと思いますが、ほかにも group-odd
などほとんどの擬似クラスと組み合わせられます。
in-*
<div tabindex="0">
<p class="opacity-50 in-focus:opacity-100">
Curabitur praesent molestie iaculis elementum vulputate orci.
</p>
</div>
v4.0 から導入された in-*
を使えば、祖先要素に特定のクラスを追加することなく、祖先要素の状態によって子孫要素をスタイリングできます。
ただし、in-*
はすべての祖先要素に反応するので、たとえば in-hover:
だと、body
にも反応してしまいます。なので基本的には group-*
のほうが有用かと思いますが、後述特定の要素内でスタイルを変える方法としては便利かもしれません。
ネストされた祖先要素の状態によるスタイリング
<div class="group">
<a href="https://example.com/">Hello world!</a>
<div class="invisible group-hover:visible group/child">
<a href="https://example.com/child/">Child</a>
<div class="invisible group-hover/child:visible">
<a href="https://example.com/child/grandchild/">Grandchild</a>
</div>
</div>
</div>
たとえば、マウスホバーしたときに下層メニューを表示するようなネストされたナビゲーションでは、group
だけだと最下層のメニューまで表示されてしまいます。group/*
のようにそれぞれのグループに名前をつけることでこの問題を解決できます。スタイリングしたい要素には group-hover/*
のようなバリアントをつけます。
子要素を一括指定
<dl class="[&>dt]:font-bold">
<dt>Foo</dt>
<dd>Semper cursus dictumst.</dd>
<dt>Bar</dt>
<dd>Dapibus rhoncus nec.</dd>
</dl>
上記は特定の子要素を指定する方法ですが、すべての子要素の場合は下記のように *
を使って短く書けます。li
などのスタイリングで便利です。
<ul class="*:border-b">
<li>1st</li>
<li>2nd</li>
<li>3rd</li>
</ul>
上記は [&>*]:border-b
に相当します。
_
を使う
子孫要素の一括指定は <ul class="[&_a]:block">
<li><a href="http://example.com/">1st</a></li>
<li><a href="http://example.com/">2nd</a></li>
<li><a href="http://example.com/">3rd</a></li>
</ul>
通常の任意値同様スペースが必要な場合は _
を使います。
要素の任意の状態によってスタイルを変える
<h1 class="text-black [&.active]:text-red-500">
Hello world!
</h1>
通常時の色は黒ですが、active
というクラスが追加されたら赤になります。特定の CSS クラスが動的に付与されるケースに対応できます。
特定の要素内でスタイルを変える
<body class="home">
<h1 class="text-black [body.home_&]:text-red-500">
Hello world!
</h1>
</body>
基本は黒ですが、home
ページでだけ赤になります。
<body class="group home">
<h1 class="text-black group-[.home]:text-red-500">
Hello world!
</h1>
</body>
v3.2 で追加されたダイナミック group-*
でも書けます。
<body class="home">
<h1 class="text-black in-[body.home]:text-red-500">
Hello world!
</h1>
</body>
v4.0 で追加された in-*
を使えば、body
に group
を追加する必要がなくなります。
max-width
メディアクエリの <h2 class="sr-only lg:not-sr-only">
Menu
</h2>
Tailwind CSS では通常メディアクエリは min-width
を使ったモバイルファーストになっているので、上記のようにモバイルでは非表示にしたい場合、デスクトップでスタイルを戻す必要がありました。
<h2 class="max-lg:sr-only">
Menu
</h2>
max-*
バリアントを使えば元に戻すという手間が不要になります。プロパティが複数ある場合はかなりわかりやすく書けるようになります。
ダイナミックブレークポイント
<h1 class="text-7xl min-[1440px]:text-[5vw]">
Hello world!
</h1>
特殊なブレークポイントのために、いちいち設定を追加する必要がなくなります。
CSS ファイル内で Tailwind CSS で設定されている値を使う
レガシー
h1 {
font-size: min(5vw, theme(fontSize.7xl));
}
CSS ファイル内での基本的なスタイリングは @apply text-7xl;
のように記述できますが、関数などで値のみを利用したい場合は theme()
関数で実現できます。theme()
関数の引数は tailwind.config.js
の theme
や extend
のプロパティに対応しています。
v4.0 以上でも利用できますが非推奨になりましたので代わりに以下の方法を利用してください。
v4.0 以上
h1 {
font-size: min(5vw, var(--text-7xl));
}
v4.0 から設定値はすべて CSS カスタムプロパティとして :root
に出力されるのでそのまま利用できます。
任意値内で Tailwind CSS で設定されている値を使う
レガシー
<h1 class="text-[min(5vw,theme(fontSize.7xl))]">
Hello world!
</h1>
CSS ファイル同様、任意値内でも theme()
関数を利用することで Tailwind CSS テーマの設定値を使うことができます。こちらも 4.0 以上でも利用できますが非推奨だと思います。
v4.0 以上
<h1 class="text-[min(5vw,var(--text-7xl))]">
Hello world!
</h1>
こちらも CSS ファイル内と同様、CSS カスタムプロパティをそのまま利用できます。
--alpha()
関数で色の透明度を変更
h1 {
background: --alpha(var(--color-red-500) / 25%);
}
v4.0 から導入された機能。任意値でも利用できますが、その場合は /
を利用したほうがいいと思います。
h1 {
background: theme(colors.red.500 / 25%);
}
v3.x でも theme()
関数を利用すればテーマで設定された色の透明度を変更できます。
<h1 class="bg-[theme(colors.red.500/25%))]">
Hello world!
</h1>
任意値でも利用可能。
おわりに
以上の記述方法を活用すれば、特殊なケースでも CSS を個別に書いたり、@theme
や tailwind.config.js
でカスタマイズしたりする必要性を減らせます。開発速度が上がるうえ、メンテナンスコストも減るのでぜひご活用ください。
Discussion