
# ディレクティブ

ディレクティブは、入力CSSに記述してTailwindの出力を組み合わせ、拡張し、順序付ける、`@`で始まるat-ruleです。このページでは`@apply`、`@utility`、`@variant`、`@custom-variant`、`@layer`を説明します。`@theme`は[テーマ](https://tailwindphp.inline0.dev/ja/docs/usage/theme)、`@plugin`は[プラグイン](https://tailwindphp.inline0.dev/ja/docs/plugins)、`@source`は[@source](https://tailwindphp.inline0.dev/ja/docs/usage/source)で説明しています。

## `@apply`

`@apply`は既存ユーティリティの宣言を独自のセレクターにインライン化します。ネストしたセレクターやメディアクエリ内も含め、セマンティックなクラスにユーティリティのスタイルを適用できます。

```php
use TailwindPHP\tw;

$css = tw::generate('<div class="btn">', '
    @import "tailwindcss";

    @theme { --color-brand: #3b82f6; }

    .btn {
        @apply px-4 py-2 rounded-lg bg-brand text-white;
    }
');
```

バリアントは`@apply`のリスト内で使えます。`@apply bg-blue-500 hover:bg-blue-600;`は`:hover`状態に展開され、`@apply px-4 md:px-6 lg:px-8;`などのレスポンシブなプレフィックスは対応する`@media`ルールを出力します。important修飾子も適用されます（`@apply !flex;`）。ネストしたセレクターにも対応しているため、`.card { h2 { @apply text-xl font-bold; } }`のようなルールで、ネストした`h2`にユーティリティを適用できます。

`@apply`はステートメントです。`@apply px-4 { … }`に本文を付けるとエラーになります。破線付きの識別子のみを列挙した`@apply`（`@apply --my-mixin;`）は、[CSSミックスイン草案](https://drafts.csswg.org/css-mixins-1/#apply-rule)にあるCSSミックスインであり、ユーティリティリストではないため、TailwindPHPでは解決されません。同じ`@apply`にミックスインとユーティリティを含めるとエラーになります（`You cannot use @apply with both mixins and utilities…`）。ミックスインルールは現在、出力に引き継がれず破棄されます（[#12](https://github.com/inline0/tailwindphp/issues/12)）。

## `@utility`

`@utility`はTailwindのエンジンに組み込まれるカスタムユーティリティを登録します。`utilities`レイヤーに並び、組み込みと同じようにバリアントを使えます。静的ユーティリティでは固定の本文を指定します。

```css
@utility content-auto {
    content-visibility: auto;
}
```

通常のユーティリティなので、バリアントは自動的に合成されます（`hover:content-auto`、`md:content-auto`）。本文では`@apply`やネストしたセレクターも使えます。

```css
@utility btn-primary {
    @apply px-4 py-2 bg-blue-500 text-white rounded;
}

@utility card {
    color: red;
    &:hover { color: blue; }
}
```

機能的ユーティリティは、名前に`-*`の接尾辞を使い、`--value()`で一致した値を読み取ります。

```css
@theme {
    --gutter-wide: 3rem;
}

@utility gutter-* {
    padding-inline: --value(--gutter-*, [length]);
    padding-inline: --spacing(--value(integer));
}
```

`--value()`は候補の値をソースごとに順に解決します。テーマの名前空間（`--gutter-*`）、データ型付きの任意の値（`[length]`）、または基本の値型（`integer`、`number`、`percentage`、`ratio`）です。`--value()`が解決できない宣言は破棄されるため、宣言を重ねてフォールバックチェーンを作れます。

| クラス | 出力 |
|---|---|
| `gutter-wide` | `padding-inline: var(--gutter-wide);` |
| `gutter-[5px]` | `padding-inline: 5px;` |
| `gutter-4` | `padding-inline: calc(var(--spacing) * 4);` |

`--modifier()`も`/`の後の部分を同じ方法で解決します。本文に`line-height: --modifier(integer);`があると、`gutter-4/7`も`line-height: 7`を出力します。ユーティリティ名はTailwindCSSのv4.3.3ルールに従います。`/`は最大1つ、`%`は末尾の数字の後にのみ置け、ドットは数字の間にのみ置けます。

## `@variant`

`@variant`は、ユーティリティを定義せずに、独自のCSS内の宣言にバリアントを適用します。

```css
.card {
    color: red;

    @variant hover {
        color: blue;
    }

    @variant dark {
        color: white;
    }
}
```

```css
.card {
  color: red;
}
@media (hover: hover) {
  .card:hover {
    color: #00f;
  }
}
@media (prefers-color-scheme: dark) {
  .card {
    color: #fff;
  }
}
```

バリアントはスタックでき（`@variant hover:focus`）、カンマ区切りで列挙したり、互いにネストしたり、独自の`@custom-variant`sを指定したりできます。本文のないトップレベルの`@variant`、または`@slot`を伴うものは、後方互換性のため`@custom-variant`として扱われます。

## `@custom-variant`

`@custom-variant`は、新しいバリアントを定義し、任意のユーティリティの前に付けられるようにします。簡略形式では、バリアント名とセレクターまたはアットルールを括弧内に指定します。

セレクターリストのバリアントでは、要素を表すために`&`を使います。

```css
@custom-variant hocus (&:hover, &:focus);
```

`hocus:bg-blue-500`は続いて`:hover`ルールと`:focus`ルールの両方を出力します。属性形式も同じように使えます。

```css
@custom-variant loading (&[data-loading="true"]);
```

アットルールのバリアントは、一致したユーティリティをそのアットルールで囲みます。

```css
@custom-variant tablet (@media (min-width: 600px));
```

カスタムバリアントは組み込みバリアントとスタックできます。`sm:hocus:bg-blue-500`は`sm`メディアクエリ内に`hocus`セレクターをネストします。より複雑なケースでは、`@slot`でユーティリティの宣言を挿入する位置を示すブロック形式を使います。

```css
@custom-variant child {
    & > * {
        @slot;
    }
}

@custom-variant sidebar-open {
    .sidebar-open & {
        @slot;
    }
}
```

## `@layer`

`@layer`は、ネイティブのCSSカスケードレイヤーを使ってカスケード順序を制御します。単独の`@layer`ステートメントでレイヤーの順序を宣言すると、セレクターの詳細度にかかわらず、後のレイヤーが優先されます。Tailwindの標準的な順序は次のとおりです。

```css
@layer theme, base, components, utilities;
```

`@import "tailwindcss"`は、内部でまさにこの設定を行います。独自の順序を宣言するか、複数のステートメント（`@layer reset, base;`の後に`@layer components, utilities;`）に分けて指定できます。また、ブロックを使ってルールを名前付きレイヤーに割り当てられます。

```php
use TailwindPHP\tw;

$css = tw::generate('<article><h1>Title</h1></article>', '
    @import "tailwindcss";

    @layer base {
        h1 { font-size: var(--text-2xl); }
        a  { color: var(--color-blue-600); text-decoration-line: underline; }
    }
');
```

`@layer base`で基本スタイルを追加すると、`components`と`utilities`より下位に配置されるため、ユーティリティクラスで要素の既定スタイルを常に上書きできます。ユーティリティより下位に置くコンポーネントクラスの`@layer components { … }`にも同じことが当てはまります。匿名レイヤーと、`@import`上の`layer()`修飾子については[Imports](https://tailwindphp.inline0.dev/ja/docs/usage/imports)を参照してください。

## 次のステップ

- [Theme](https://tailwindphp.inline0.dev/ja/docs/usage/theme) — `@theme`トークンとテーマ関数。
- [Imports](https://tailwindphp.inline0.dev/ja/docs/usage/imports) — `@import`、仮想モジュール、`layer()`修飾子。
- [Plugins](https://tailwindphp.inline0.dev/ja/docs/plugins) — `@plugin`ディレクティブとプラグインAPI。
- [@source](https://tailwindphp.inline0.dev/ja/docs/usage/source) — スキャンするファイルとクラスを制御します。
