
# Direktiven

Direktiven sind At-Regeln mit Präfix `@`, die du in dein Eingabe-CSS schreibst, um Tailwinds Ausgabe zusammenzusetzen, zu erweitern und anzuordnen. Diese Seite behandelt `@apply`, `@utility`, `@variant`, `@custom-variant` und `@layer`. `@theme` wird unter [Theme](https://tailwindphp.inline0.dev/de/docs/usage/theme) behandelt, `@plugin` unter [Plugins](https://tailwindphp.inline0.dev/de/docs/plugins) und `@source` unter [@source](https://tailwindphp.inline0.dev/de/docs/usage/source).

## `@apply`

`@apply` fügt die Deklarationen vorhandener Utilities in deinen eigenen Selektor ein. Damit kannst du Utility-Stile einer semantischen Klasse zuweisen, auch innerhalb verschachtelter Selektoren und Media Queries.

```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;
    }
');
```

Varianten funktionieren in einer `@apply`-Liste: `@apply bg-blue-500 hover:bg-blue-600;` erweitert den Zustand `:hover`, und responsive Präfixe wie `@apply px-4 md:px-6 lg:px-8;` geben die entsprechenden `@media`-Regeln aus. Auch der Important-Modifikator wird berücksichtigt (`@apply !flex;`). Verschachtelte Selektoren werden unterstützt, sodass eine Regel wie `.card { h2 { @apply text-xl font-bold; } }` Utilities auf das verschachtelte `h2` anwendet.

`@apply` ist eine Anweisung: `@apply px-4 { … }` mit einem Block führt zu einem Fehler. Ein `@apply`, das nur durch Bindestriche getrennte Bezeichner enthält (`@apply --my-mixin;`), ist ein CSS-Mixin aus dem Entwurf zu [CSS-Mixins](https://drafts.csswg.org/css-mixins-1/#apply-rule) und keine Utility-Liste. Daher löst TailwindPHP es nicht auf. Ein Mixin und Utilities in dasselbe `@apply` zu schreiben, führt zu einem Fehler (`You cannot use @apply with both mixins and utilities…`). Mixin-Regeln werden derzeit aus der Ausgabe entfernt, statt unverändert übernommen zu werden ([#12](https://github.com/inline0/tailwindphp/issues/12)).

## `@utility`

`@utility` registriert eine benutzerdefinierte Utility in Tailwinds Engine. Sie wird in die Ebene `utilities` einsortiert und akzeptiert wie integrierte Utilities Varianten. Eine statische Utility hat einen festen Block:

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

Als echte Utility lassen sich Varianten automatisch kombinieren (`hover:content-auto`, `md:content-auto`). Der Block kann selbst `@apply` und verschachtelte Selektoren verwenden:

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

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

Eine funktionale Utility verwendet im Namen das Suffix `-*` und liest den gefundenen Wert mit `--value()` aus:

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

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

`--value()` prüft den Wert des Kandidaten nacheinander gegen jede Quelle: einen Theme-Namespace (`--gutter-*`), einen beliebigen Wert mit Datentyp (`[length]`) oder einen Wert ohne Präfix (`integer`, `number`, `percentage`, `ratio`). Wird der Wert einer Deklaration über `--value()` nicht aufgelöst, wird sie verworfen. Wenn du die Deklarationen stapelst, entsteht eine Fallback-Kette:

| Klasse | Ausgabe |
|---|---|
| `gutter-wide` | `padding-inline: var(--gutter-wide);` |
| `gutter-[5px]` | `padding-inline: 5px;` |
| `gutter-4` | `padding-inline: calc(var(--spacing) * 4);` |

`--modifier()` löst den Teil nach einem `/` genauso auf: Wenn `line-height: --modifier(integer);` im Body steht, gibt `gutter-4/7` auch `line-height: 7` aus. Für Utility-Namen gelten die Regeln von TailwindCSS v4.3.3: höchstens ein `/`, `%` nur am Ende nach einer Ziffer und Punkte nur zwischen Ziffern.

## `@variant`

`@variant` wendet eine Variante auf Deklarationen in deinem eigenen CSS an, ohne ein Utility zu definieren:

```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;
  }
}
```

Varianten lassen sich stapeln (`@variant hover:focus`), durch Kommas auflisten, ineinander verschachteln und können eigene `@custom-variant`s benennen. Ein `@variant` auf oberster Ebene ohne Body oder mit `@slot` wird aus Gründen der Abwärtskompatibilität als `@custom-variant` behandelt.

## `@custom-variant`

`@custom-variant` definiert eine neue Variante, die du jedem Utility voranstellen kannst. Die Kurzform benennt die Variante und gibt einen Selektor oder eine At-Regel in Klammern an.

Eine Selektorliste-Variante verwendet `&` für das Element:

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

`hocus:bg-blue-500` gibt dann sowohl die Regeln für `:hover` als auch für `:focus` aus. Eine Attributform funktioniert genauso:

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

Eine At-Regel-Variante umschließt passende Utilities mit dieser At-Regel:

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

Benutzerdefinierte Varianten lassen sich mit integrierten stapeln – `sm:hocus:bg-blue-500` verschachtelt den Selektor `hocus` in der Media Query `sm`. Für komplexere Fälle verwendest du die Blockform; `@slot` markiert darin die Stelle, an der die Deklarationen des Utility eingefügt werden:

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

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

## `@layer`

`@layer` steuert die Kaskadenreihenfolge mithilfe nativer CSS-Kaskadenschichten. Eine alleinstehende `@layer`-Anweisung legt die Reihenfolge der Schichten fest; spätere Schichten haben unabhängig von der Selektorspezifität Vorrang. Die kanonische Reihenfolge von Tailwind lautet:

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

Genau das richtet `@import "tailwindcss"` intern ein. Du kannst eine eigene Reihenfolge festlegen oder sie auf mehrere Anweisungen verteilen (`@layer reset, base;` und dann `@layer components, utilities;`) und Regeln mit einem Block einer benannten Schicht zuweisen:

```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; }
    }
');
```

Wenn du Basisstile über `@layer base` hinzufügst, bleiben sie unter `components` und `utilities`, sodass eine Utility-Klasse immer deine Element-Standards überschreibt. Dasselbe gilt für `@layer components { … }` bei Komponentenk lassen, die unter den Utilities liegen sollen. Anonyme Schichten und `layer()`-Modifikatoren auf `@import` werden unter [Imports](https://tailwindphp.inline0.dev/de/docs/usage/imports) behandelt.

## Nächste Schritte

- [Theme](https://tailwindphp.inline0.dev/de/docs/usage/theme) — `@theme`-Tokens und Theme-Funktionen.
- [Imports](https://tailwindphp.inline0.dev/de/docs/usage/imports) — `@import`, virtuelle Module und `layer()`-Modifikatoren.
- [Plugins](https://tailwindphp.inline0.dev/de/docs/plugins) — die `@plugin`-Direktive und die API des Plugins.
- [@source](https://tailwindphp.inline0.dev/de/docs/usage/source) — steuere, welche Dateien und Klassen durchsucht werden.
