27. Januar 2026
Warum Entwickler nach Primary fragen statt nach Blau
Du definierst Farben. Entwickler fragen ständig nach "primary" und "background.paper". Dieser Artikel erklärt warum. Ohne Code, ohne Fachjargon, und ohne das Gefühl, etwas verpasst zu haben.
Sascha Becker
Author16 Min. Lesezeit
Warum Entwickler nach Primary fragen statt nach Blau
Vor ein paar Tagen habe ich mich mit unserem Designer zusammengesetzt, um Farben abzustimmen. Es lief nicht gut, nicht weil jemand falsch lag, sondern weil wir dasselbe Problem mit völlig unterschiedlichen Denkmodellen gelöst haben.
Er hatte monatelang solide, gründliche Arbeit geleistet: jeden Screen mit exakten Hex-Werten annotiert, jede Farbe dokumentiert, jedes Element berücksichtigt. Aus seiner Sicht hatte er die Farben bereits definiert und festgelegt, wo sie hinkommen. Erledigt.
Auf unserer Seite stellten wir seltsame Fragen. „Welche ist primary?" „Was meinst du? Das ist Blau." „Und dieses Grau auf den Karten, ist das background.paper?" „Ich hab dir doch gesagt, es ist Grau. Steht im Dokument."
Er hatte nicht unrecht. Sein System funktionierte, bis es auf unseres traf. Und unser System hat Namen, die seltsam klingen, wenn sie niemand jemals erklärt hat.
Darum geht es in diesem Artikel. Nicht „warum Entwickler Recht haben". Sondern warum wir bei genau diesem System gelandet sind, welches Problem es löst und wie, sobald wir das Vokabular teilen, die Übergabe zwischen Design und Entwicklung für beide Seiten dramatisch einfacher wird.
Dein Ansatz: und seine Grenzen
Farben über ihren Hex-Wert zu definieren und zu dokumentieren, wo jede hinkommt, ist ein völlig vernünftiger Ansatz. Er ist explizit, visuell und eindeutig. Wenn jemand fragt „welche Farbe hat dieser Karten-Hintergrund?", kannst du auf #F5F5F5 zeigen, und es gibt keine Unklarheit.
Das funktioniert gut, wenn:
- Die App nur einen visuellen Modus hat (nur hell)
- Die Farbpalette klein und stabil ist
- Jede Farbe nur an wenigen Stellen vorkommt
Es wird schwierig, wenn:
- Die Marke sich weiterentwickelt. Dein Blau wird Lila. Jetzt muss jede Screen-Annotation, die „Blau" oder
#3B82F6sagt, aktualisiert werden, in den Design-Dateien und im Code. Bei 200 Referenzen sind das 200 manuelle Änderungen auf beiden Seiten. - Dark Mode ins Spiel kommt. Das
#F5F5F5Grau, das du für Karten-Hintergründe definiert hast? Im Dark Mode muss es#1E1E1Esein. Jetzt brauchst du zwei Farbdokumente, und jeder Screen braucht zwei Annotationen. Der Aufwand verdoppelt sich. - Zwei Farben gleich aussehen, aber unterschiedliche Zwecke erfüllen. Ein hellgrauer Karten-Hintergrund und hellgrauer deaktivierter Text können heute denselben Hex-Wert teilen. Aber nächste Woche soll der deaktivierte Text etwas dunkler sein. Wenn beide als „Grau" dokumentiert sind, riskiert eine Änderung die andere mitzuändern.
Nichts davon sind Design-Fehler. Es sind Skalierungsprobleme. Und Entwickler sind vor Jahren auf genau dieselben Probleme gestoßen, nur von der Code-Seite aus.
Wie Entwickler hier gelandet sind
Wir haben nicht mit Themes angefangen. Wir sind durch Jahre derselben Frustrationen dort angekommen.
Es begann mit Duplizierung. Am Anfang bauten wir ein separates Element für jede visuelle Variante: ein blauer Button, ein roter Button, ein kleiner blauer Button, ein großer roter Button. Jede Kombination war ein eigenes Ding. „Blau" in der ganzen App zu ändern bedeutete, durch Dutzende von Dateien zu suchen.
Die erste Lösung waren wiederverwendbare Komponenten: ein Button, den man mit Optionen wie Größe und Farbe konfiguriert, statt für jede Kombination einen neuen zu bauen. Wenn du Figma benutzt, kennst du das bereits: Es ist genau das, was eine Figma-Komponente mit Varianten macht. Eine Komponente, viele Konfigurationen.
Die zweite Lösung war Farben zentral zu verwalten. Statt denselben Hex-Wert über das Projekt verstreut zu haben, speicherten wir ihn an einer Stelle und referenzierten ihn überall. Einmal ändern, überall aktualisiert. Du machst dasselbe mit Figma-Stilen, eine Farbe definieren, über die Datei hinweg anwenden.
Die dritte Lösung war Farben nach Rolle statt nach Aussehen zu benennen. Statt eine Variable „Blau" zu nennen, nannten wir sie „Primary". Statt „Grau" sagten wir „Surface". Warum? Weil „Blau" nicht mehr stimmt, sobald die Marke nicht mehr blau ist. „Primary" bedeutet immer „die Hauptmarkenfarbe", unabhängig davon, welche Farbe das tatsächlich ist.
Der letzte Schritt war, all diese rollenbasierten Farben in einem zentralen Objekt zu bündeln: dem Theme. Eine Datei, die die gesamte visuelle Identität definiert. Jedes Element in der App liest daraus. Theme ändern, und die ganze App aktualisiert sich, inklusive Dark Mode, der einfach ein zweites Theme mit anderen Werten für dieselben Rollen ist.
Das ist die gesamte Reise. Sie ist nicht kompliziert, aber wenn sie einem niemand erklärt, kann das Ergebnis, ein Entwickler, der nach „Primary" fragt statt „Blau" zu akzeptieren, unnötig pedantisch wirken.
Der alte Weg, eine separate Komponente für jede visuelle Variante:
jsx<BlueButton>Speichern</BlueButton><RedButton>Löschen</RedButton><SmallBlueButton>Bearbeiten</SmallBlueButton>
Der neue Weg, eine Komponente, über Props konfiguriert:
jsx<Button color="primary" size="large">Speichern</Button><Button color="error">Löschen</Button><Button color="primary" size="small">Bearbeiten</Button>
Gleiches Ergebnis, aber jetzt gibt es nur noch einen Button zu pflegen.
Was ist ein Theme?

Stell dir ein Theme vor wie einen Dresscode für deine Anwendung.
Ein Dresscode sagt nicht „trag den marineblauen Blazer mit dem weißen Hemd und den braunen Schuhen". Er sagt „Business Casual". Alle erscheinen passend gekleidet, aber niemand brauchte eine Anleitung für jedes Kleidungsstück.
Ein Theme funktioniert genauso. Es sagt einem Button nicht „sei #6366F1". Es sagt dem Button „verwende die Primary-Farbe". Was Primary ist, das wird einmal definiert, an einer Stelle, und alles in der App hält sich daran.
Das macht ein Theme mächtig:
- Eine Änderung, überall. „Primary" von Blau auf Lila aktualisieren, und jedes primär gefärbte Element passt sich automatisch an.
- Dark Mode gratis. Ein dunkles Theme ist einfach ein zweiter Satz Werte für dieselben Rollen. „Primary" ist immer noch „Primary", es sieht nur im Dunkeln anders aus.
- Automatische Konsistenz. Wenn ein Button, ein Link und ein Chip alle „Primary" sind, stimmen sie immer überein. Kein Risiko, dass einer
#3B82F6ist und ein anderer#3B83F6wegen eines Tippfehlers.
Das ist das tatsächliche Theme-Objekt, mit dem Entwickler arbeiten. Beachte: Es sind nur Rollennamen und Hex-Werte, dieselben Informationen, die man in ein Design-Dokument schreiben würde, nur in einem strukturierten Format.
jsconst theme = createTheme({palette: {primary: { main: "#6366F1" },secondary: { main: "#EC4899" },error: { main: "#EF4444" },warning: { main: "#F59E0B" },info: { main: "#3B82F6" },success: { main: "#22C55E" },background: {default: "#FAFAFA",paper: "#FFFFFF",},text: {primary: "#1E293B",secondary: "#64748B",},},});
Einen beliebigen Wert hier ändern, und jede Komponente in der App aktualisiert sich automatisch.
Warum nicht einfach Blau nennen?

Das war genau die Frage in unserem Gespräch, und sie verdient eine echte Antwort.
Weil der Name Veränderung überleben muss.
„Blau" beschreibt, wie die Farbe gerade aussieht. „Primary" beschreibt, was die Farbe tut. Das eine ist eine Momentaufnahme, das andere eine Rolle.
Stell dir folgendes Szenario vor: Du hast deine Hauptmarkenfarbe als Blau definiert und über 40 Screens annotiert. Das Marketing entscheidet sich für ein Rebranding zu Lila. Mit Farbnamen:
- „Blau" → überall falsch. Jede Referenz ist jetzt eine Lüge. Du und das Entwicklungsteam müssen überall suchen und ersetzen.
- „Primary" → immer noch korrekt. Du änderst einen Wert im Theme. Fertig.
Dieselbe Logik gilt für jeden rollenbasierten Namen im System. „Error" wird immer „etwas ist schiefgelaufen" bedeuten, ob es heute rot oder morgen orange ist. „Surface" wird immer „der Hintergrund einer Karte oder eines Dialogs" bedeuten, ob es im hellen Modus weiß oder im dunklen Modus anthrazit ist.
Semantische Namen sind stabile Bezeichner. Sie beschreiben die Aufgabe einer Farbe, nicht das Aussehen. Deshalb bestehen Entwickler darauf, nicht um schwierig zu sein, sondern weil es die einzige Benennung ist, die nicht bricht, wenn sich Dinge ändern.
Was ist background.paper?
Hierüber sind wir am meisten gestolpert, also gehen wir es direkt an.
Der Name kommt von Material Design. Googles Designsystem, auf dem unsere Komponentenbibliothek (Material UI) aufbaut. Material Design verwendet eine physische Metapher: Die Oberfläche besteht aus Materialbögen auf verschiedenen Ebenen, wie Papiere, die auf einem Schreibtisch gestapelt sind.
background.defaultist der Schreibtisch, die Basisebene, der Seitenhintergrund.background.paperist ein Blatt Papier auf diesem Schreibtisch, eine Karte, ein Dialog, ein Dropdown, eine Sidebar. Alles, was visuell „über" der Seite liegt.
Bei der Benennung geht es nicht um die Farbe. Es geht um die Ebene. In einem hellen Theme ist „Paper" vielleicht Weiß. In einem dunklen Theme vielleicht Dunkelgrau. In beiden Fällen bedeutet es dasselbe: die Oberflächenfarbe für erhöhte Elemente.
Deshalb reicht „Grau" nicht. „Grau" sagt dir die Farbe. „Paper" sagt dir wo und warum, und genau das müssen Designer und Entwickler kommunizieren.
Man muss den Namen nicht lieben. Aber wenn man weiß, dass er „Karten-/Dialog-/Erhöhte-Oberflächen-Hintergrund" bedeutet, ist er tatsächlich schneller als einen Hex-Wert für jede Karte auf jedem Screen anzugeben.
Was das Theme für dich übernimmt
Sobald du die Kernpalette definiert hast, macht das Theme mehr, als nur deine Farben zu speichern, es arbeitet aktiv mit ihnen. Komponenten leiten Hover-Zustände, Fokus-Ringe und Schatten automatisch ab. Hellere und dunklere Varianten werden für dich generiert. Zu verstehen, was das Theme von sich aus erledigt, hilft dir zu vermeiden, Dinge zu spezifizieren, die bereits abgedeckt sind.
Kann ich transparente Farben im Theme verwenden?
Das kam auf, als wir über Hover-Zustände und dezente Hintergründe sprachen. Die kurze Antwort: Nein. Theme-Farben sollten immer deckend sein.
Der Grund ist, dass Komponenten Transparenz bereits selbst handhaben. Wenn ein Button einen Hover-Effekt hat, verwendet er keine separate „Hover-Farbe" aus dem Theme. Stattdessen nimmt er die bestehende Theme-Farbe und wendet seine eigene Transparenz an, zum Beispiel 8 % Deckkraft für ein dezentes Hover, 12 % für einen Fokus-Zustand, 20 % für einen gedrückten Zustand. Schatten, Ripples und Overlays funktionieren alle gleich: Sie leiten ihre Transparenz von der soliden Grundfarbe ab.
Wenn du eine Theme-Farbe definierst, die bereits halbtransparent ist, sagen wir, ein Erfolgsgrün mit 50 % Deckkraft, stapeln sich diese automatischen Transparenzebenen darauf. Das Ergebnis ist unvorhersehbar: Hover-Zustände, die kaum sichtbar sind, Ripples, die ausgewaschen aussehen, oder Elemente, die je nach Hintergrund ihr Aussehen ändern.
Die Regel ist einfach:
- Im Theme: definiere solide, deckende Farben.
- In einer bestimmten Komponente: wenn du Transparenz für eine bestimmte Designentscheidung brauchst, wende sie dort an, nicht im Theme.
Tip
Denk an Theme-Farben wie an Zutaten, nicht an fertige Gerichte. Ein Koch (die Komponente) entscheidet, wie viel von jeder Zutat verwendet wird. Wenn du die Zutaten vorverdünnst, schmeckt jedes Rezept falsch.
Das hält das System vorhersehbar. Jede Komponente kann sich darauf verlassen, dass die Theme-Farbe ein stabiler, deckender Wert ist, und ihre eigene Transparenz nach Bedarf anpassen.
Was ist mit primary.light und primary.dark?
Wenn du primary.main im Theme definierst, generiert Material UI automatisch zwei zusätzliche Varianten: primary.light (eine hellere Version) und primary.dark (eine dunklere Version). Es berechnet auch primary.contrastText, die Textfarbe, die Lesbarkeit vor der Hauptfarbe sicherstellt.
Der Instinkt aus Design-Perspektive ist, diese manuell anzugeben. Und das kannst du. MUI erlaubt es. Aber es gibt einen Grund, warum die Standardwerte existieren: Die generierten Varianten werden unter Berücksichtigung des wahrgenommenen Kontrasts abgeleitet, nicht einfach nur „heller machen" oder „dunkler machen". Der Algorithmus stellt sicher, dass helle und dunkle Varianten eine konsistente visuelle Beziehung zur Hauptfarbe über die gesamte Palette hinweg beibehalten.
Manuelles Überschreiben ist nicht falsch, erzeugt aber zusätzlichen Aufwand:
- Du musst Kontrastverhältnisse für Barrierefreiheit überprüfen (WCAG AA erfordert mindestens 4,5:1 für normalen Text).
- Du musst drei Werte statt einem aktualisieren, wenn sich die Markenfarbe ändert.
- Du riskierst Inkonsistenzen, wenn
primary.lightundsecondary.lightmit unterschiedlicher Logik abgeleitet wurden.
Die praktische Empfehlung: Starte mit den berechneten Varianten. Wenn eine bestimmte Variante für dein Design nicht richtig aussieht, überschreibe diese eine. Aber behandle die generierten Werte als vernünftige Standardwerte, nicht als Platzhalter, die du ausfüllen musst.
Komponenten und die Palette
Nachdem das Theme definiert, was jede Farbrolle bedeutet, ist die nächste Frage: Wie verwenden Komponenten sie tatsächlich? Die Kurzversion, sie wählen ihre Farben nicht selbst. Sie leihen sie aus der Palette, und du bestimmst, welche Rolle sie verwenden.

Komponenten leihen Farben
Wenn du Figma benutzt, verstehst du Komponenten bereits intuitiv. Eine Figma-Komponente mit Varianten funktioniert genau wie eine Code-Komponente mit konfigurierbaren Optionen:
| In Figma | Im Code |
|---|---|
| Du erstellst eine „Button"-Komponente | Entwickler erstellen einen Button |
| Du fügst Variante Größe = Klein hinzu | Sie setzen size = "small" |
| Du fügst Variante Stil = Outlined hinzu | Sie setzen variant = "outlined" |
| Du fügst Variante Farbe = Primary hinzu | Sie setzen color = "primary" |
Ein Button. Viele Konfigurationen. Kein „SmallBlueButton" und „LargeRedButton" als separate Dinge.
Die zentrale Erkenntnis: Eine Komponente besitzt ihre Farben nicht. Ein Button weiß nicht, dass er blau ist. Er weiß, dass er „Primary" ist. Das Theme entscheidet, wie „Primary" aussieht. Das ist dasselbe wie einen Figma-Farbstil auf eine Komponente anzuwenden: die Komponente referenziert den Stil, nicht den rohen Hex-Wert. Stil ändern, und jede Komponente, die ihn verwendet, aktualisiert sich.
Ein Button enthält keine Farbwerte. Er sagt einfach „ich bin Primary", und das Theme füllt den Rest aus:
jsx// Der Button referenziert eine Rolle, keine Farbe<Button color="primary">Änderungen speichern</Button><Button color="error">Konto löschen</Button>// Eine Card verwendet automatisch den „Paper"-Hintergrund<Card><CardContent><Typography color="text.primary">Benutzerprofil</Typography><Typography color="text.secondary">Zuletzt aktiv vor 2h</Typography></CardContent></Card>
Keine Hex-Werte irgendwo. Wenn das Theme von Blau auf Lila wechselt, aktualisieren sich diese Komponenten, ohne eine einzige Zeile zu ändern.
Das Rollensystem
Das ist der vollständige Satz an Farbrollen in Material UI, das Vokabular, das wir dich bitten zu teilen, nicht als Code, sondern als gemeinsame Sprache:
| Rolle | Bedeutung | Verwendet in |
|---|---|---|
| Primary | Die Hauptmarkenfarbe | Haupt-Buttons, aktive Tabs, Links, wichtige Hervorhebungen |
| Secondary | Ein ergänzender Akzent | Toggle-Switches, Auswahlsteuerungen, Floating Action Buttons |
| Error | Etwas ist schiefgelaufen oder destruktiv | Fehlermeldungen, Löschen-Buttons, Formularvalidierung |
| Warning | Vorsicht: noch kein Fehler | Warnbanner, Bestätigungsdialoge für riskante Aktionen |
| Info | Neutrale Information, keine Dringlichkeit | Tooltips, Informationsbadges, Hilfetext |
| Success | Ein positives Ergebnis | Erfolgsmeldungen, Abschluss-Häkchen |
| Background (default) | Der Basis-Seitenhintergrund: der „Schreibtisch" | Die Hintergrundfarbe der App |
| Background (paper) | Erhöhte Oberflächen: das „Papier auf dem Schreibtisch" | Karten, Dialoge, Dropdowns, Menüs, Drawer |
| Text (primary) | Die Haupttextfarbe, hohe Gewichtung | Überschriften, Fließtext |
| Text (secondary) | Abgeschwächter Text, geringere Wichtigkeit | Bildunterschriften, Zeitstempel, Hilfetext, Labels |
Das sind zehn Rollen. Mit diesen zehn kann eine gesamte Anwendung konsistent eingefärbt werden: über hellen Modus, dunklen Modus und jedes zukünftige Marken-Update hinweg.
Nur zehn Rollen?
Man kann das Theme um eigene Farben erweitern, für Spezialfälle wie Datenvisualisierungen oder Marketing-Highlights. Aber die Einschränkung ist beabsichtigt.
Je mehr Rollen hinzukommen, desto schwieriger wird das System zu pflegen, und desto unwahrscheinlicher ist es, dass jede Komponente sie konsistent verwendet. Ein Theme mit 30 eigenen Rollen ist nur eine Tabelle mit Hex-Werten mit zusätzlichen Schritten. Zehn Rollen erzwingen Entscheidungen darüber, was wichtig ist, und genau diese Disziplin sorgt dafür, dass das System über Modi, Marken und zukünftige Änderungen hinweg funktioniert, ohne auseinanderzufallen.
Dein neuer Workflow

Hier ist der praktische Gewinn. Statt jeden Screen mit Hex-Werten zu annotieren, kannst du eine Theme-Definition liefern, ein Dokument, das Rollen auf deine gewählten Farben abbildet:
| Rolle | Farbe | Zweck |
|---|---|---|
| Primary | #6366F1Indigo | Markenfarbe, Hauptaktionen |
| Secondary | #EC4899Pink | Akzente, sekundäre Aktionen |
| Error | #EF4444Rot | Fehler, destruktive Aktionen |
| Warning | #F59E0BAmber | Warnungen, Vorsichtszustände |
| Info | #3B82F6Blau | Informationselemente |
| Success | #22C55EGrün | Erfolgszustände |
| Background | #FAFAFAHellgrau | Seitenhintergrund |
| Paper | #FFFFFFWeiß | Karten, Dialoge, erhöhte Oberflächen |
| Text primary | #1E293BFast-Schwarz | Überschriften, Fließtext |
| Text secondary | #64748BGrau | Bildunterschriften, Hilfetext |
Das ist die gesamte Übergabe. Eine Tabelle. Daraus konfiguriert ein Entwickler das komplette Theme, und jede Komponente in der App verwendet automatisch die richtigen Farben.
Für einzelne Screens musst du nur Rollen referenzieren:
- „Dieser Button ist Primary", nicht „dieser Button ist
#6366F1" - „Diese Karte verwendet den Paper-Hintergrund", nicht „diese Karte ist weiß"
- „Diese Meldung ist ein Error", nicht „dieser Text ist rot"
Deine Design-Dokumente werden kürzer und stabiler. Kein Aktualisieren von 40 Screens mehr, wenn sich eine Farbe ändert. Keine Mehrdeutigkeit mehr, welches Grau welches ist. Und Entwickler können deine Designs schneller umsetzen, weil der Übersetzungsschritt entfällt.
Dieselbe Sprache sprechen
Es geht nicht darum, dass Entwickler Designern vorschreiben, wie sie arbeiten sollen. Es geht darum, eine Sprache zu finden, die beide Seiten fließend sprechen.
Du bringst das visuelle Urteilsvermögen ein, welche Farben richtig aussehen, welche Kombinationen die richtige Stimmung und Hierarchie erzeugen. Diese Expertise ändert sich nicht. Was sich ändert, ist das Format der Übergabe: Statt 200 Hex-Annotationen über Screens verteilt, definierst du 10 Rollen an einer Stelle. Weniger Arbeit, mehr Klarheit, und ein System, das skaliert.
Wenn du „Primary" statt „Blau" sagst und „Paper" statt „Weiß", lernst du keinen Entwickler-Jargon um seiner selbst willen. Du verwendest stabile Namen, die sich direkt in funktionierenden Code übersetzen, Markenwechsel überleben, Dark Mode unterstützen und die gesamte Codebasis konsistent halten.
Das Theme ist ein Vertrag zwischen Design und Entwicklung. Sobald beide Seiten ihn verstehen, verschwindet die Reibung, und wir können aufhören, über Farbnamen zu debattieren, und anfangen, zusammen zu bauen.
Quellen & Weiterführende Links
- Material Design Theming Overview
Googles offizieller Leitfaden zu Material Theming, wie Themes Konsistenz über Komponenten hinweg gewährleisten.
- Material Design 3: Color Roles
Offizielle M3-Dokumentation zu Farbrollen: Primary, Secondary, Tertiary, Surface und ihre semantische Bedeutung.
- MUI Theming-Dokumentation
MUIs offizieller Leitfaden zum Theme-Objekt, ThemeProvider und wie Komponenten Theme-Werte konsumieren.
- MUI Palette-Anpassung
Detaillierte Referenz für die MUI-Palette: Primary, Secondary, Error, Warning, Info, Success, Background und Text.
- Material Design 3: Wie das Farbsystem funktioniert
Erklärt, wie Schlüsselfarben tonale Paletten generieren und auf Farbrollen in Material Design 3 abgebildet werden.
