Store-View-spezifisches Styling und White-Labeling im Hyvä-Theme
AI generated
Hyvä
phtml
Hyvä Theme, Tailwind CSS, Multi-Brand
Store-View-spezifisches Styling
White-Labeling mit gemeinsamer Codebasis

Mehrere Marken über eine einzige Hyvä-Codebasis auszuliefern, klingt einfach, solange es nur um ein anderes Logo geht. Sobald Farbpaletten, Schriftgroessen und ganze Abstandssysteme pro Marke variieren sollen, entscheidet die Wahl zwischen CSS-Variablen und separaten Tailwind-Configs darueber, wie wartbar das Setup in einem Jahr noch ist.

12 Min. Lesezeit White-Labeling Tailwind CSS Multi-Brand

1. Ausgangslage: mehrere Marken, eine Codebasis

Während Magentos Fallback-Hierarchie und ViewModel-basierte Store-Erkennung regeln, welcher Layout-Inhalt und welche Übersetzung pro Store-View ausgeliefert werden, beantwortet das eine andere Frage nicht: Woher kommen die eigentlichen Design-Werte wie Markenfarbe, Akzentfarbe und Schriftgroesse, wenn zwei Marken auf demselben Theme-Code laufen sollen. Genau diese Design-Token-Ebene steht in diesem Artikel im Mittelpunkt, nicht die inhaltliche Store-Erkennung selbst.

Ein realistisches Szenario ist ein Betreiber, der unter zwei Store-Views zwei unterschiedliche Marken fuehrt, mit eigenem Logo, eigener Farbwelt und teils eigener Typografie, aber identischer Produktdatenbank und identischer Checkout-Logik. Ein kompletter Theme-Fork pro Marke wäre technisch möglich, fuehrt aber langfristig zu doppelt gepflegtem Code bei jeder Bugfix- oder Feature-Änderung.

2. CSS Custom Properties: Tailwind @theme mit var()-Referenzen

Tailwind CSS v4 im CSS-first-Ansatz definiert Design-Tokens direkt im @theme-Block als CSS Custom Properties. Statt feste Hex-Werte einzutragen, verweisen die Tailwind-Variablen auf allgemeine CSS-Variablen wie --brand-primary, deren tatsaechlicher Wert erst zur Laufzeit im Browser aufgeloest wird, abhaengig davon, welche Store-spezifische CSS-Datei zuletzt geladen wurde.

Der große Vorteil ist, dass ein einziger, kompilierter Tailwind-Build für alle Marken ausreicht, jede Utility-Klasse wie bg-brand-primary bleibt exakt gleich, nur der dahinterliegende Farbwert unterscheidet sich pro Store. Der Nachteil zeigt sich bei tiefgreifenden strukturellen Unterschieden, etwa wenn eine Marke grundsaetzlich größere Abstaende oder eine andere Schriftfamilie braucht, denn reine Farbwerte über CSS-Variablen zu steuern ist einfach, ganze Spacing-Skalen dagegen deutlich muehsamer.


/* web/tailwind/tailwind-source.css */
@theme {
  --color-brand-primary: var(--store-brand-primary, #ea580c);
  --color-brand-accent: var(--store-brand-accent, #fb8570);
}

/* web/css/store-brand-a.css, per Store-View über Layout-XML geladen */
:root {
  --store-brand-primary: #0f4c81;
  --store-brand-accent: #7fb2e5;
}

3. Separate Tailwind-Builds pro Marke

Die Alternative ist ein eigenstaendiger Tailwind-Build je Marke, jeweils mit eigenem @theme-Block und eigenem, fest kodierten Farb- und Abstandssystem, aber demselben zugrunde liegenden phtml-Template-Code. Hyväs hyva.config.json unterstützt mehrere Theme-Verzeichnisse innerhalb desselben Vendor-Namespaces, sodass sich pro Marke ein eigenes web/tailwind-Verzeichnis mit eigenem Build-Output anlegen lässt.

Dieser Ansatz eignet sich, sobald Marken sich nicht nur in Farben, sondern strukturell unterscheiden, etwa unterschiedliche Border-Radius-Werte, komplett andere Schriftgroessen-Skalen oder sogar unterschiedliche Grid-Systeme. Der Preis dafuer ist ein eigener Build-Prozess und eine eigene, ausgelieferte CSS-Datei pro Marke, was den Deployment-Workflow komplexer macht als eine einzelne, universelle CSS-Datei.


{
  "themes": {
    "Mironsoft/brand-a": {
      "css-file": "tailwind/tailwind-source.css"
    },
    "Mironsoft/brand-b": {
      "css-file": "tailwind/tailwind-source.css"
    }
  }
}

4. Trade-off: Laufzeitflexibilitaet gegen Build-Zeit-Optimierung

CSS-Variablen sind zur Laufzeit flexibel: Ein neuer Store mit einer neuen Akzentfarbe braucht lediglich eine neue, kleine CSS-Datei mit den passenden Custom Properties, kein neuer Tailwind-Build und kein neues Deployment der kompilierten Basis-Datei. Das macht diesen Ansatz ideal für Reseller-Modelle mit vielen, ähnlich strukturierten Marken, bei denen sich hauptsaechlich die Farbpalette unterscheidet.

Separate Configs bieten dagegen bessere Build-Zeit-Optimierung, weil Tailwinds Purge-Mechanismus pro Marke exakt nur die tatsaechlich genutzten Utility-Klassen in die finale CSS-Datei aufnimmt, ohne ungenutzte CSS-Variablen-Definitionen für Marken mitzuschleppen, die auf dieser Instanz gar nicht existieren. Bei nur zwei bis drei strukturell ähnlichen Marken ueberwiegt in der Praxis meist der Wartungsvorteil der CSS-Variablen-Lösung.

5. Wie das Theme-Fallback-System store-spezifisches CSS laedt

Die store-spezifische CSS-Datei mit den Custom-Property-Ueberschreibungen wird nicht hart im Basis-Template verlinkt, sondern über ein eigenes Layout-XML-Handle pro Store-View eingebunden, etwa default_storeview_brand_a.xml, das Magentos Fallback-Hierarchie automatisch nur für den passenden Store aufloest. So bleibt die Zuordnung von Marke zu Store-View deklarativ und ohne Code-Verzweigung im PHP oder im Template steuerbar.

Wichtig ist, die Store-spezifische CSS-Datei nach der kompilierten Tailwind-Basis-Datei zu laden, damit die Custom-Property-Ueberschreibungen tatsaechlich greifen und nicht durch die Standardwerte im @theme-Block ueberschrieben werden. Die Ladereihenfolge im head-Block entscheidet hier direkt darueber, ob das White-Labeling sichtbar wird oder nicht.


<!-- app/design/frontend/Mironsoft/default/Magento_Theme/layout/default_storeview_brand_a.xml -->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <css src="css/store-brand-a.css"/>
    </head>
</page>

6. Asset-Austausch: Logo, Favicon und Social-Bilder pro Store-View

Neben Farben gehoert der Austausch von Bild-Assets zum Kern jedes White-Labeling-Setups. Magentos Store-Design-Konfiguration erlaubt bereits im Adminbereich, Logo und Favicon pro Store-View unabhaengig zu setzen, ohne dass dafuer eigener Theme-Code nötig ist, solange das Logo-Template im Theme brav über $block->getLogoSrc() statt über einen hart kodierten Pfad arbeitet.

Für Social-Media-Vorschaubilder und weitere Meta-Assets, die nicht über die Standard-Store-Design-Konfiguration abgedeckt sind, bietet sich ein eigenes ViewModel an, das den aktuellen Store ermittelt und den passenden Asset-Pfad aus einer Konfigurations-Map zurueckgibt, statt diese Zuordnung über verstreute Bedingungen in mehreren Templates zu pflegen.

7. Tailwind-Safelist-Fallstricke bei dynamischen Brand-Klassen

Ein häufiger Fehler bei CSS-Variablen-basiertem Multi-Brand-Styling ist, Klassennamen dynamisch aus PHP oder JavaScript zusammenzusetzen, etwa 'bg-brand-' . $brandSlug. Tailwinds Purge-Prozess scannt Templates nur nach vollstaendigen, statischen Klassennamen und erkennt solche zusammengesetzten Strings nicht, wodurch die betroffene Utility-Klasse im finalen Build schlicht fehlt.

Die zuverlaessige Lösung ist, ausschliesslich vollstaendig ausgeschriebene Klassennamen wie bg-brand-primary zu verwenden und die eigentliche Markenunterscheidung komplett auf die Ebene der CSS-Variablen zu verlagern, nicht auf die Ebene der Klassennamen selbst. Damit bleibt der Purge-Scan zuverlaessig, unabhaengig davon, wie viele Marken später noch hinzukommen.

8. Deployment-Workflow für mehrere Marken gleichzeitig

Beim CSS-Variablen-Ansatz bleibt der Deploy-Ablauf unveraendert gegenueber einem Single-Brand-Setup: Ein Tailwind-Build, ein setup:static-content:deploy-Aufruf für alle Stores gemeinsam, die store-spezifischen CSS-Dateien mit den Custom-Property-Ueberschreibungen sind schlank genug, um ohne separate Build-Schritte direkt mit deployt zu werden.

Bei separaten Tailwind-Configs pro Marke braucht jede Marke einen eigenen Build-Durchlauf vor dem eigentlichen Static-Content-Deploy, und der Deploy-Befehl selbst muss pro Theme-Verzeichnis mit dem passenden -t-Flag aufgerufen werden. Das lässt sich gut automatisieren, sollte aber bewusst in CI-Skripten dokumentiert werden, damit bei neuen Marken kein Build-Schritt vergessen wird.


# Separate Configs: Build pro Marke, dann gemeinsamer Deploy
bin/npm --prefix app/design/frontend/Mironsoft/brand-a/web/tailwind run build
bin/npm --prefix app/design/frontend/Mironsoft/brand-b/web/tailwind run build
bin/magento setup:static-content:deploy de_DE -t Mironsoft/brand-a -f
bin/magento setup:static-content:deploy de_DE -t Mironsoft/brand-b -f

9. Langfristige Wartbarkeit: Design-Tokens dokumentieren

Je mehr Marken auf derselben Codebasis laufen, desto wichtiger wird eine zentrale Übersicht aller verfügbaren Design-Tokens, idealerweise als eigene Markdown-Datei oder Storybook-ähnliche Referenzseite, die dokumentiert, welche CSS-Variable welchen visuellen Zweck erfüllt. Ohne diese Dokumentation setzt jede neue Marke ihre eigenen, leicht abweichenden Variablennamen und die Konsistenz erodiert Schritt für Schritt.

Regressionsrisiko entsteht vor allem dort, wo ein gemeinsames Template unbeabsichtigt markenspezifische Annahmen enthält, etwa eine hart kodierte Farbe statt einer Variable in einem selten getesteten Randbereich wie der Fehlerseite. Ein kurzer visueller Regressionstest pro Marke bei jedem Theme-Release, selbst nur als Screenshot-Vergleich, faengt solche Fälle zuverlaessiger ab als eine rein manuelle Durchsicht.

Ansatz Build-Aufwand Laufzeitflexibilitaet Wartbarkeit Empfehlung für
CSS Custom Properties Gering, ein gemeinsamer Build Hoch, neue Marke ohne neuen Build Hoch bei aehnlicher Struktur Viele, strukturell ähnliche Marken
Separate Tailwind-Configs Hoch, ein Build pro Marke Gering, Änderung braucht neuen Build Mittel, mehr Dateien zu pflegen Wenige Marken mit strukturellen Unterschieden
Kompletter Theme-Fork Sehr hoch, unabhaengige Codebasen Sehr hoch, völlig frei Sehr gering, doppelte Pflege bei jedem Fix Nur bei radikal unterschiedlichen Marken
Store-Design-Konfiguration (Assets) Gering, Admin-Konfiguration Hoch, sofort im Adminbereich aenderbar Hoch, kein Code-Eingriff nötig Logo, Favicon und einfache Asset-Wechsel

Mironsoft

Hyvä-Theme-Entwicklung und Luma-Migration

Noch auf Luma unterwegs oder ein Hyvä-Theme, das nicht rund läuft?

Wir entwickeln Hyvä-Themes für Magento von Grund auf oder migrieren bestehende Luma-Shops sauber, mit Tailwind CSS, Alpine.js und ohne unnötiges JavaScript-Gepäck.

Luma-zu-Hyvä-Migration

Bestehenden Shop strukturiert und ohne Funktionsverlust auf Hyvä umstellen.

Custom-Theme-Entwicklung

Individuelles Hyvä-Theme nach Design-Vorgaben von Grund auf umsetzen.

Performance-Optimierung

Core Web Vitals und Ladezeiten im Hyvä-Frontend gezielt verbessern.

10. Zusammenfassung

White-Labeling in Hyvä

CSS-Variablen für Farbwelten

Tailwind @theme mit var()-Referenzen erlaubt neue Marken ohne neuen Build, solange sich hauptsaechlich Farben unterscheiden.

Separate Configs bei struktureller Abweichung

Sobald sich Abstaende, Schriftgroessen oder Grids grundlegend unterscheiden, lohnt sich ein eigener Tailwind-Build je Marke.

Ladereihenfolge entscheidet über Wirkung

Store-spezifisches CSS muss nach der kompilierten Basis-Datei geladen werden, sonst greifen die Custom-Property-Ueberschreibungen nicht.

Vollstaendige Klassennamen für sicheren Purge

Dynamisch zusammengesetzte Tailwind-Klassennamen werden vom Purge-Scan übersehen, Markenunterscheidung gehoert auf CSS-Variablen-Ebene.

11. FAQ: White-Labeling in Hyvä

1Was ist der Unterschied zwischen CSS-Variablen und separaten Tailwind-Configs für Multi-Brand-Setups?
CSS-Variablen erlauben einen gemeinsamen Tailwind-Build für alle Marken, wobei nur die Werte der Custom Properties pro Store variieren. Separate Configs bauen für jede Marke ein eigenes, unabhaengiges Tailwind-Stylesheet mit eigenem Design-System.
2Wann lohnt sich ein kompletter Theme-Fork statt Design-Tokens zu variieren?
Nur wenn Marken sich nicht nur visuell, sondern auch strukturell in Layout und Funktionsumfang stark unterscheiden. Für reine Farb- und Typografie-Unterschiede ist ein Fork fast immer unnoetiger Wartungsaufwand.
3Wie lade ich store-spezifisches CSS nur für einen bestimmten Store-View?
Über ein eigenes Layout-XML-Handle wie default_storeview_brand_a.xml, das Magentos Fallback-Hierarchie automatisch nur für den passenden Store aufloest, ganz ohne Bedingungen im PHP-Code.
4Warum greifen meine CSS-Variablen-Ueberschreibungen nicht?
Meist liegt es an der Ladereihenfolge: Die store-spezifische CSS-Datei muss nach der kompilierten Tailwind-Basis-Datei geladen werden, sonst ueberschreiben die Standardwerte aus dem @theme-Block die Store-spezifischen Werte.
5Kann ich Tailwind-Klassennamen dynamisch aus PHP zusammensetzen, etwa bg-brand- plus Markenname?
Nicht zuverlaessig, Tailwinds Purge-Scan erkennt nur vollstaendige, statische Klassennamen in Templates. Dynamisch zusammengesetzte Strings fuehren dazu, dass die Utility-Klasse im finalen Build fehlt.
6Wie tausche ich Logo und Favicon pro Store-View aus?
Über Magentos Store-Design-Konfiguration im Adminbereich, sofern das Theme-Template über $block->getLogoSrc() statt über einen hart kodierten Pfad arbeitet, ganz ohne zusätzlichen Code.
7Wie unterscheidet sich dieser Artikel von einem Artikel über Fallback-Hierarchie und Store-Erkennung?
Dieser Artikel behandelt die Design-Token-Ebene, also woher Farb- und Abstandswerte pro Marke stammen. Fallback-Hierarchie und ViewModel-basierte Store-Erkennung sind ein separates Thema auf Layout- und Inhaltsebene.
8Muss ich für jede neue Marke einen neuen Tailwind-Build erstellen?
Beim CSS-Variablen-Ansatz nein, eine neue, kleine CSS-Datei mit den passenden Custom Properties reicht. Bei separaten Tailwind-Configs pro Marke ist ein eigener Build-Durchlauf nötig.
9Wie deploye ich mehrere Marken mit separaten Tailwind-Configs gleichzeitig?
Jede Marke braucht einen eigenen Build-Aufruf, gefolgt von einem eigenen setup:static-content:deploy-Aufruf mit dem passenden -t-Flag für das jeweilige Theme-Verzeichnis.
10Wie verhindere ich Regressionen, wenn mehrere Marken dieselbe Codebasis teilen?
Eine zentrale Dokumentation aller Design-Tokens sowie ein kurzer visueller Regressionstest pro Marke bei jedem Theme-Release, selbst als einfacher Screenshot-Vergleich, fangen hart kodierte, markenspezifische Annahmen zuverlaessig ab.