🌬

Tailwind CSS の一歩進んだ書き方

2022/05/22に公開約7,100字

Changelog

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 とは何か」については理解している前提で進めます。

html
<h1 class="text-3xl font-bold underline">
  Hello world!
</h1>

簡単な例として、上記 HTML を記述すると、以下のようにスタイリングされます。

スタイリングされた Hello world! のスクリーンショット

Just-in-Time 改め arbitrary values

上記例にある text-3xl などのスタイルは予め Tailwind CSS が用意しているものですが、tailwind.config.js を編集することで簡単に変更・追加できます。ただし、1 回しか使わないスタイルでもいちいち tailwind.config.js に登録しないといけないので、その不便さを解消する機能として v2.1 から Just-in-Time (JIT) モードが導入されました。

v3.0 からは JIT がデフォルトになりましたので、わざわざ「JIT モード」ということもなくなり、ドキュメントではその機能を単に arbitrary values (任意値) と記述しています。

html
<h1 class="text-[10vw] font-bold underline">
  Hello world!
</h1>

text-[10vw] のように記述することで、登録されていないスタイルでも以下の CSS が自動的に生成されます。

css
.text-\[10vw\] {
  font-size: 10vw;
}

スタイリングされた Hello world! のスクリーンショット

一歩進んだ記述方法まとめ

しかし、自由度が増したことで記述方法が複雑になってきましたので、それらはまとめていきます。

シンプルな任意値

html
<h1 class="text-[10vw]">
  Hello world!
</h1>

マイナス値は角括弧内で

html
<h1 class="ml-[-1em]">
  Hello world!
</h1>

通常では -ml-1 のように先頭に - をつけますが、任意値は [] の中に記述します。

値に calc() clamp() などを使う場合はスペースをつめる

html
<h1 class="text-[clamp(32px,2.5vw+24px,48px)]">
  Hello world!
</h1>

スペースが必要な値は代わりに _ を使う

html
<h1 class="drop-shadow-[0_0_1em_#0ff]">
  Hello world!
</h1>

データ型の明示

html
<h1 class="text-[length:var(--title-size)] text-[color:var(--title-color)]">
  Hello world!
</h1>

text- のように、色やサイズの複数プロパティが一つの名前を共有しているケースがあります。text-[22px] text-[#bada55] を記述すると、サイズなのか色なのかは、値から自動的に判別されます。しかし、CSS カスタムプロパティなど、値から判別できない場合があります。このようなときは length:color: などで明示することができます。CSS カスタムプロパティ以外でも、たとえば background-sizebg-[length:200px_100px] のようにデータ型を明示する必要があったりします。

CSS カスタムプロパティ

html
<h1 class="[--viewport-from:320] [--viewport-to:960] [--min-font-size:32] [--max-font-size:48]">
  Hello world!
</h1>

以前投稿した「CSS カスタムプロパティによる流動的フォントサイズ」のように、要素に CSS カスタムプロパティを設定することでスタイリングするようなケースで重宝されます。

任意のプロパティ

html
<h1 class="animate-bounce [animation-delay:3s]">
  Hello world!
</h1>

用意されていないプロパティは上記の [animation-delay:3s] のように書けます。アニメーションの細かい調整も可能になります。

::before ::after などの疑似要素・擬似クラス

html
<h1 class="after:content-['👋🏼']">
  Hello world!
</h1>

::before ::after 以外にもさまざまな疑似要素・擬似クラスが用意されています。こちらの一覧表をご覧ください。

data 属性

html
<h1 class="text-2xl data-[size=large]:text-3xl">
  Hello world!
</h1>

通常は text-2xl ですが、data-size="large" がある場合は text-3xl になります。

祖先要素の状態によるスタイリング

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 などほとんどの擬似クラスと組み合わせられます。

ネストされた祖先要素の状態によるスタイリング

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/* のようなバリアントをつけます。

色の透明度は / で指定可能

html
<h1 class="text-black/75 bg-red-500/[0.15]">
  Hello world!
</h1>

任意値も使用可能です。

!!important

html
<h1 class="!font-normal">
  Hello world!
</h1>

! をつけることで !important にすることができます。Tailwind CSS メインのプロジェクトではほとんど使うことはないと思いますが、保守案件など途中から Tailwind CSS を導入した場合は重宝すると思います。ほかへの影響もほぼないのでわりとカジュアルに使えます。

子要素を一括指定

html
<ul class="[&>li]:border-b">
  <li>1st</li>
  <li>2nd</li>
  <li>3rd</li>
</ul>

子孫要素の一括指定は _ を使う

html
<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>

通常の任意値同様スペースが必要な場合は _ を使います。

状態によってスタイルを変える

html
<h1 class="text-black [&.active]:text-red-500">
  Hello world!
</h1>

通常時の色は黒ですが、active というクラスが追加されたら赤になります。特定の CSS クラスが動的に付与されるケースに対応できます。

特定の要素内でスタイルを変える

html
<body class="home">
  <h1 class="text-black [body.home_&]:text-red-500">
    Hello world!
  </h1>
</body>

基本は黒ですが、home ページでだけ赤になります。

html
<body class="group home">
  <h1 class="text-black group-[.home]:text-red-500">
    Hello world!
  </h1>
</body>

v3.2 で追加されたダイナミック group-* でも書けます。

メディアクエリの max-width

html
<h2 class="sr-only lg:not-sr-only">
  Menu
</h2>

Tailwind CSS では通常メディアクエリは min-width を使ったモバイルファーストになっているので、上記のようにモバイルでは非表示にしたい場合、デスクトップでスタイルを戻す必要がありました。

html
<h2 class="max-lg:sr-only">
  Menu
</h2>

max-* バリアントを使えば元に戻すという手間が不要になります。プロパティが複数ある場合はかなりわかりやすく書けるようになります。

ダイナミックブレークポイント

html
<h1 class="text-7xl min-[1440px]:text-[5vw]">
  Hello world!
</h1>

特殊なブレークポイントのために、いちいち screens に設定を追加する必要がなくなります。

おわりに

以上の記述方法を活用すれば、特殊なケースでも CSS を個別に書いたり、tailwind.config.js をカスタマイズしたりする必要がほぼなくなります。開発速度が上がるうえ、メンテナンスコストも減るのでぜひご活用ください。


Discussion

ログインするとコメントできます