Zum Inhalt springen
duxt

Theming

Wie das Theme gebaut ist — eigene Komponenten, eine Token-Ebene und ein Dark Mode, der über eine Klasse schaltet.

Das Theme ist keine Abhängigkeit, die du konfigurierst. Es ist ein Satz Dateien, die die Ebene besitzt, gebaut auf shadcn-vue und Tailwind 4 — und der Grund für diese Form entscheidet, was dich das Überschreiben kostet.

Etwas ändern ist Das Theme überschreiben. Diese Seite erklärt, warum die Nähte dort sitzen, wo sie sitzen.

Komponenten werden kopiert, nicht importiert

shadcn-vue ist keine Komponentenbibliothek, die du installierst. Ihr CLI schreibt den Quelltext einer Komponente in dein Projekt, und von da an gehört die Datei dir. Die Ebene hält ihre Primitive in app/components/ui/, und components.json zeigt das CLI auf diesen Alias — eine hinzuzufügen ist ein einziger Befehl.

Zwei Folgen ergeben sich, und sie laufen in entgegengesetzte Richtungen:

  • Du kannst alles ändern, ohne Fork. Eine Komponente, die anders aussehen soll, ist eine Datei, die du bearbeitest — es gibt kein Upstream, gegen das du ankämpfst, und keine Theme-API, in der du eine Lücke suchst.
  • Nichts aktualisiert sich von selbst. Eine Korrektur an einem Primitiv erreicht dich, wenn du das CLI erneut dafür aufrufst, nicht wenn eine Abhängigkeit springt. Die Ebene trägt diese Kosten für ihre eigenen Primitive; eine Komponente, die du in deinem Projekt überschreibst, trägst du.

Dieser Tausch ist der ganze Grund für die dritte Stufe im Überschreib-Leitfaden: die kleinste Änderung, die die Aufgabe erledigt, ist die richtige — denn eine Komponente, die du ersetzt, ist eine Komponente, die du ab jetzt pflegst.

Eine Token-Ebene, zwei Stylesheets

Die Palette besteht aus CSS-Custom-Properties in oklch, einmal auf :root definiert und auf .dark neu definiert. Jede Komponente liest ein Token; keine hält eine Farbe. Genau das macht eine einzeilige Überschreibung möglich — du definierst --primary in deinem eigenen Stylesheet neu, und jede Fläche, die es nutzt, zieht mit.

Zwei Dateien tragen das, und sie sind nicht austauschbar:

DateiEnthält
app/assets/css/duxt.cssPalette, Tailwind-Einstieg, das Preset der Ebene — die Datei, die du liest
app/assets/css/typeset.cssshadcns Typeset, wortgleich übernommen — die Datei, die du nicht bearbeitest

Hinter typeset.css steht kein Registry-Eintrag, das CLI kann sie also weder holen noch aktualisieren. Ein Upgrade heißt: Datei erneut herunterladen. Deshalb gehören lokale Änderungen ins Preset von duxt.css — eine Änderung in typeset.css ist eine, die das nächste Upgrade stillschweigend verwirft.

Dark Mode ist eine Klasse, keine Media Query

@custom-variant dark (&:is(.dark *)) — das Theme schaltet über eine dark-Klasse, und @nuxtjs/color-mode setzt genau diese Klasse, weil die Ebene es mit classSuffix: '' konfiguriert.

Das ist das Detail, über das man beim Überschreiben einer Farbe stolpert. Ein Token, das nur unter @media (prefers-color-scheme: dark) definiert ist, wird nie gelesen; ein Token, das einmal auf :root steht, gilt in beiden Modi — und ist damit in einem von beiden falsch. Definiere in beiden Blöcken neu, oder nimm in Kauf, dass ein Modus den Wert der Ebene behält.

Die Palette weicht bewusst von shadcns Standard ab

--muted-foreground ist hier dunkler, als der neutrale shadcn-Satz ihn ausliefert. Dieses Token trägt die Seitenbeschreibungen, das Inhaltsverzeichnis und den Brotkrumenpfad, und bei shadcns Wert misst es auf den Flächen, auf denen es tatsächlich landet, unter den 4,5:1, die WCAG AA verlangt.

Keine browserbasierte Prüfung fängt das: ein Accessibility-Lauf über die gebauten Seiten hat keine berechnete Farbe zu messen. Die Ebene misst deshalb die Tokens selbst, in tests/contrast.test.ts, und paart jede Vordergrundfarbe mit den Hintergründen, auf denen sie wirklich verwendet wird. Überschreibst du ein Vordergrund-Token, übernimmst du diese Zusicherung — der Test liest die Datei der Ebene, nicht deine.

Tailwind muss erfahren, wo die Ebene liegt

@source '../../../app' steht weit oben in duxt.css und ist keine Zierde. Tailwind sucht Klassennamen ab der Build-Wurzel, und das ist das Verzeichnis des konsumierenden Projekts. Die Ebene liegt außerhalb davon, in node_modules — ohne diese Zeile fehlte also jede von einer Ebenen-Komponente genutzte Utility im erzeugten CSS: eine Website, die vollkommen ungestylt rendert.

Der Pfad ist relativ zum Stylesheet und gilt daher überall, wo das Paket installiert ist.

Was das für dich heißt

  • Eine Farbe, ein Radius, eine Schrift: Token im eigenen Stylesheet neu definieren.
  • Ein Layout, das für deine Website falsch ist: Komponente per Namen überschatten.
  • Ein Primitiv, das die Ebene nicht mitbringt: mit dem CLI hinzufügen.

Jede Stufe abwärts kostet mehr Pflege als die darüber. Der Überschreib-Leitfaden geht alle drei durch, und Deiner Website eine Marke geben behandelt den Teil, der Identität statt Theme ist — Name, Marke und Icons.

War diese Seite hilfreich?