THEMING APP

THEMING APP

 Einbinden der Theming-App

Du kannst die API der Theming-App als Script-Link referenzieren:


<script src="/theming/import"></script>

Hinweis

Das Script der Theming-Api sollte möglichst früh eingebunden werden, um eine kurze Darstellung der Ressource in den Standard-Farben zu verhindern.

 Wie kann ich die Farben von der Theming-App konsumieren?

 1. Möglichkeit: CSS-Variablen

Das Script der Theming-API sorgt dafür, dass die Farben der Theming-App in deiner Ressource im :root-Selektor gesetzt werden. Außerdem werden die uns bekannten Fehler und Ungenauigkeiten in den CSS-Klassen von Material behoben. Falls du die Standardklassen von Material verwendest oder dein Framework auf diesen CSS-Klassen aufbaut, ist die Einbindung der Theming-App jetzt abgeschlossen. Überprüfe danach einmal im hellen und im dunklen Standarddesign, ob die Farben überall richtig übernommen wurden.

Hinweis

Der Link-Tag für die CSS-Variablen wird an den Anfang des HTML-Heads gesetzt, die CSS-Fixes ans Ende.

 Definieren eines Fallback-Themes

Falls die Theming-App nicht erreichbar ist, verwendet die Theming-API das Standarddesign der d.velop AG. Für den Fall, dass die Initialisierung der Theming-API fehlschlägt, kannst du eine CSS-Datei mit den CSS-Variablen in deinem Projekt erstellen und referenzieren. Diese CSS-Datei sollte dann dvelopThemingFallback.css heißen. Wenn die Theming-API erfolgreich initialisiert wurde, wird dieser Link-Tag entfernt.

 Verhindern der Einbindung von CSS-Variablen

Wenn window.ignoreCSSTheme auf true gesetzt ist, werden die CSS-Variablen und CSS-Fixes nicht in deine Ressource eingebunden.


<script>
    window.ignoreCSSTheme = true;
</script>
<script src="/theming/import"></script>

 2. Möglichkeit: JSON

Du kannst die Theming-Farben auch als JSON konsumieren. Dazu wird ein Event verschickt, sobald die Farbwerte verfügbar sind:


let theme;
if( window.themingInstance && window.themingInstance.GetJSON() ) {
    theme = JSON.parse( window.themingInstance.GetJSON() );
    ...
} else {
    window.addEventListener('dvelopThemingLoaded', () => {
        theme = JSON.parse( window.themingInstance.GetJSON() );
        ...
    });
}

Wichtig

Die JSON-Werte müssen von deiner App verarbeitet werden, bevor sie in der Oberfläche wirksam werden. Um ein Flackern während der Navigation zu verhindern, sollte zumindest die Hintergrundfarbe der Ressource über CSS bezogen werden.

 Welche Vorteile bietet die Theming-App?

 Zentralisierung von benutzerspezifischen Farbwerten

Wenn du die Theming-App nutzt, musst du dich nicht mehr darum kümmern, welche Farben deine App verwenden soll. Die Theming-App liefert dir die Farben des Designschemas, das der aktuell angemeldete Benutzer ausgewählt hat. Wie du die Farben verwendest, hängt von dem GUI-Framework ab, das du verwendest. Die Anwender können dann zwischen verschiedenen Designschemas (hell, dunkel, barrierefrei, etc.) wechseln.

 Barrierefreiheit

Wenn du die Theming-App nutzt, kannst du deine App barrierefreier gestalten. Das im Standard verfügbare barrierefreie Theme sorgt dafür, dass Material-Elemente einen besseren Kontrast haben und dass um fokussierte Elemente ein Rahmen erscheint:


*:focus:not(.theming-no-focus-border) {
    border: 2px solid var(--mdc-theme-primary)!important;
}

Dieser Fokus-Mechanismus funktioniert auch, wenn du kein Material-Design verwendest. Falls für ein Element explizit im fokussierten Zustand kein Rahmen angezeigt werden soll, füge dem Element die CSS-Klasse .theming-no-focus-border hinzu.

 Wie funktioniert Theming in Material-Design?

Der Theming-Mechanismus von Material baut auf 3 Farbwerten auf: Primär-, Sekundär- und Hintergrundfarbe. Die Elemente, die im Fokus stehen sollen, haben die Primärfarbe (z.B. Schaltflächen). Elemente, die einen Kontrast setzen sollen, haben die Sekundärfarbe (z.B. Checkboxen). Außerdem werden an einigen Komponenten Abstufungen der Schriftfarbe verwendet (z.B. nicht klickbare Schaltflächen).

Ein vollständiges Theme hat also folgende Attribute:

  • Primärfarbe
  • Schriftfarbe auf Primärfarbe
  • Sekundärfarbe
  • Schriftfarbe auf Sekundärfarbe
  • Fehlerfarbe
  • Schriftfarbe für Fehlerfarbe
  • Hintergrundfarbe
  • Schriftfarbe für Hintergrundfarbe
  • Abstufungen

In den vorgefertigten Web-Komponenten von Material wird dieses System mithilfe von CSS-Variablen umgesetzt. Du kannst die CSS-Variablen global, also im root:-Selektor setzen, um die Standard-Farben von Material zu überschreiben:


:root {
    --mdc-theme-primary: #FA1234;
    --mdc-theme-on-primary: #000000;
    --mdc-theme-secondary: #EE3460;
    --mdc-theme-on-secondary: #FFFFFF;
    --mdc-theme-surface: #FFFFFF;
    --mdc-theme-on-surface: #000000;
    --mdc-theme-background: #FFFFFF;
    --mdc-theme-on-background: #000000;
    --mdc-theme-error: #B0020;
    --mdc-theme-on-error: #FFFFFF;
    --mdc-theme-text-hint-on-background: rgba(0,0,0,0.38);
    ...
}

Allerdings hat Material den Mechanismus selbst nicht komplett konsistent umgesetzt. In manchen CSS-Klassen wird noch ein statischer Farbwert verwendet.

 Theming-Fehler, Farbkorrekturen und zusätzliche Farbwerte

Die Theming-App korrigiert die angesprochenen Theming-Fehler von Material. Außerdem werden manche Designentscheidungen von Material zugunsten eines deutlichen Kontrastes korrigiert, wie z.B. die Farben von selektierten Chips. Es werden auch zusätzliche Farbwerte, z.B. für Warnungen oder Erfolgsmeldungen ausgeliefert.

 Gelieferte Farbwerte

 CSS


:root {
    color-scheme: <light oder dark>;
    
    --mdc-theme-primary: <Primärfarbe>;
    --mdc-theme-on-primary: <Schriftfarbe auf Primärfarbe>;
    --mdc-theme-secondary: <Sekundärfarbe>;
    --mdc-theme-on-secondary: <Schriftfarbe auf Sekundärfarbe>;
    --mdc-theme-surface: <Hintergrundfarbe>;
    --mdc-theme-on-surface: <Schriftfarbe auf Hintergrundfarbe>;
    --mdc-theme-background: <Hintergrundfarbe>;
    --mdc-theme-on-background: <Schriftfarbe>;
    --mdc-theme-error: <Fehlerfarbe>;
    --mdc-theme-on-error: <Schriftfarbe auf Fehlerfarbe>;
    
    --mdc-theme-text-hint-on-background: <Schriftfarbe 38%>;
    --mdc-theme-text-primary-on-background: <Schriftfarbe 87%>;
    --mdc-theme-text-secondary-on-background: <Schriftfarbe 54%>;
    --mdc-theme-text-disabled-on-background: <Schriftfarbe 38%>;
    --mdc-theme-text-icon-on-background: <Schriftfarbe 54%>;
    --mdc-checkbox-unchecked-color: <Schriftfarbe 54%>;
    --mdc-checkbox-checked-color: <Sekundärfarbe>;
    --mdc-checkbox-disabled-color: <Schriftfarbe 38%>;
    --mdc-checkbox-ink-color: <Hintergrundfarbe 54%>;
    --mdc-theme-text-primary-on-light: <Schriftfarbe 87%>;
    --mdc-theme-text-secondary-on-light: <Schriftfarbe 54%>;
    --mdc-theme-text-hint-on-light: <Schriftfarbe 38%>;
    --mdc-theme-text-disabled-on-light: <Schriftfarbe 38%>;
    --mdc-theme-text-icon-on-light: <Schriftfarbe 70%>;
    --mdc-theme-text-icon-on-dark: <Hintergrundfarbe 50%>;
    --mdc-theme-text-disabled-on-dark: <Hintergrundfarbe 50%>;
    --mdc-theme-text-hint-on-dark: <Hintergrundfarbe 50%>;
    --mdc-theme-text-secondary-on-dark: <Hintergrundfarbe 70%>;
    --mdc-ripple-hover-opacity: <Deckkraft der Rippleeffekte beim Hover>;
    --mdc-ripple-press-opacity: <Deckkraft der Rippleeffekte beim Klick>;
    --mdc-ripple-color: <Schriftfarbe 54%>;
    
    --dmc-theme-background12: <Hintergrundfarbe 12%>;
    --dmc-theme-on-background12: <Schriftfarbe 12%>;
    --dmc-theme-background32: <Hintergrundfarbe 32%>;
    --dmc-theme-on-background32: <Schriftfarbe 32%>;
    --dmc-theme-background38: <Hintergrundfarbe 38%>;
    --dmc-theme-on-background38: <Schriftfarbe 38%>;
    --dmc-theme-background50: <Hintergrundfarbe 50%>;
    --dmc-theme-on-background50: <Schriftfarbe 50%>;
    --dmc-theme-background54: <Hintergrundfarbe 54%>;
    --dmc-theme-on-background54: <Schriftfarbe 54%>;
    --dmc-theme-background60: <Hintergrundfarbe 60%>;
    --dmc-theme-on-background60: <Schriftfarbe 60%>;
    --dmc-theme-background62: <Hintergrundfarbe 62%>;
    --dmc-theme-on-background62: <Schriftfarbe 62%>;
    --dmc-theme-background70: <Hintergrundfarbe 70%>;
    --dmc-theme-on-background70: <Schriftfarbe 70%>;
    --dmc-theme-background87: <Hintergrundfarbe 87%>;
    --dmc-theme-on-background87: <Schriftfarbe 87%>;
    --dmc-theme-disabled-text: <Disabled Text>;
    --dmc-theme-disabled-background: <Disabled Hintergrund>;
    --dmc-theme-on-disabled-background: <Schrift auf Disabled>;
    --dmc-theme-chip-color: <Chipfarbe>;
    --dmc-theme-on-chip-color: <Schriftfarbe für Chip>;
    --dmc-theme-chip-selected: <Selektierter Chip>;
    --dmc-theme-snackbar: <Hintergrundfarbe Snackbar>;
    --dmc-theme-progress: <Farbe Progressbar>;
    --dmc-theme-primary-transparent: <Primärfarbe transparent>;
    --dmc-theme-green: <Grün für Erfolgsmeldungen>;
    --dmc-theme-green-transparent: <Grün transparent>;
    --dmc-theme-yellow: <Gelb für Warnungen>;
    --dmc-theme-yellow-transparent: <Gelb transparent>;
    --dmc-theme-red-transparent: <Rot transparent>;
    --dmc-theme-smoke: <Smoke>;
    --dmc-theme-elevation--z1: <Box-Shadow für Elevation-Level 1>;
    --dmc-theme-elevation--z2: <Box-Shadow für Elevation-Level 2>;
    --dmc-theme-elevation--z3: <Box-Shadow für Elevation-Level 3>;
    --dmc-theme-elevation--z4: <Box-Shadow für Elevation-Level 4>;
    --dmc-theme-elevation--z5: <Box-Shadow für Elevation-Level 5>;
    --dmc-theme-elevation--z6: <Box-Shadow für Elevation-Level 6>;
    --dmc-theme-elevation--z7: <Box-Shadow für Elevation-Level 7>;
    --dmc-theme-elevation--z8: <Box-Shadow für Elevation-Level 8>;
    --dmc-theme-elevation--z9: <Box-Shadow für Elevation-Level 9>;
    --dmc-theme-elevation--z10: <Box-Shadow für Elevation-Level 10>;
    --dmc-theme-elevation--z11: <Box-Shadow für Elevation-Level 11>;
    --dmc-theme-elevation--z12: <Box-Shadow für Elevation-Level 12>;
    --dmc-theme-elevation--z13: <Box-Shadow für Elevation-Level 13>;
    --dmc-theme-elevation--z14: <Box-Shadow für Elevation-Level 14>;
    --dmc-theme-elevation--z15: <Box-Shadow für Elevation-Level 15>;
    --dmc-theme-elevation--z16: <Box-Shadow für Elevation-Level 16>;
    --dmc-theme-elevation--z17: <Box-Shadow für Elevation-Level 17>;
    --dmc-theme-elevation--z18: <Box-Shadow für Elevation-Level 18>;
    --dmc-theme-elevation--z19: <Box-Shadow für Elevation-Level 19>;
    --dmc-theme-elevation--z20: <Box-Shadow für Elevation-Level 20>;
    --dmc-theme-elevation--z21: <Box-Shadow für Elevation-Level 21>;
    --dmc-theme-elevation--z22: <Box-Shadow für Elevation-Level 22>;
    --dmc-theme-elevation--z23: <Box-Shadow für Elevation-Level 23>;
    --dmc-theme-elevation--z24: <Box-Shadow für Elevation-Level 24>;
    
}

 JSON


{
    "Name": "<Themename>",
    "IsDark": "<true oder false>",
    "PrimaryColor": "<Primärfarbe>",
    "SecondaryColor": "<Sekundärfarbe>",
    "BackgroundColor": "<Hintergrundfarbe>",
    "ErrorColor": "<Fehlerfarbe>",
    "OnPrimaryColor": "<Schriftfarbe auf Primärfarbe>",
    "OnSecondaryColor": "<Schriftfarbe auf Sekundärfarbe>",
    "OnBackgroundColor": "<Schriftfarbe auf Hintergrundfarbe>",
    "OnErrorColor": "<Schriftfarbe auf Fehlerfarbe>",
    "Error": "<Fehlerfarbe>",
    "Background12": "<Hintergrundfarbe 12%>",
    "OnBackground12": "<Schriftfarbe 12%>",
    "Background38": "<Hintergrundfarbe 38%>",
    "OnBackground38": "<Schriftfarbe 38%>",
    "Background32": "rgba(255,255,255,0.32)",
    "OnBackground32": "<Schriftfarbe 32%>",
    "Background50": "<Hintergrundfarbe 50%>",
    "OnBackground50": "<Schriftfarbe 50%>",
    "Background54": "<Hintergrundfarbe 54%>",
    "OnBackground54": "<Schriftfarbe 54%>",
    "Background60": "<Hintergrundfarbe 60%>",
    "OnBackground60": "<Schriftfarbe 60%>",
    "Background62": "<Hintergrundfarbe 62%>",
    "OnBackground62": "<Schriftfarbe 62%>",
    "Background70": "<Hintergrundfarbe 70%>",
    "OnBackground70": "<Schriftfarbe 70%>",
    "Background87": "<Hintergrundfarbe 87%>",
    "OnBackground87": "<Schriftfarbe 87%>",
    "RippleHoverOpacity": "<Deckkraft der Rippleeffekte beim Hover>",
    "RipplePressOpacity": "<Deckkraft der Rippleeffekte beim Klick>",
    "DisabledText": "<Disabled Text>",
    "DisabledBackground": "<Disabled Hintergrund>",
    "OnDisabledBackground": "<Schriftfarbe auf Disabled>",
    "ChipColor": "<Chipfarbe>",
    "ChipSelected": "<Farbe selektierter Chip>",
    "Snackbar": "<Hintergrundfarbe Snackbar>",
    "Progress": "<Farbe für Progressbar>",
    "Smoke": "<Smoke>",
    "PrimaryTransparent": "<Primärfarbe Transparent>",
    "Green": "<Grün für Erfolgsmeldungen>",
    "GreenTransparent": "<Grün transparent>",
    "Yellow": "<Gelb für Warnungen>",
    "YellowTransparent": "<Gelb transparent>",
    "RedTransparent": "<Rot transparent>",
    "SubtleShadow": "<Subtiler Schatten>",
    "ProminentShadow": "<Prominenterer Schatten>",
    "OnChipColor": "<Schriftfarbe für Chips>",
    "ElevationZ1": "<Box-Shadow für Elevation-Level 1>",
    "ElevationZ2": "<Box-Shadow für Elevation-Level 2>",
    "ElevationZ3": "<Box-Shadow für Elevation-Level 3>",
    "ElevationZ4": "<Box-Shadow für Elevation-Level 4>",
    "ElevationZ5": "<Box-Shadow für Elevation-Level 5>",
    "ElevationZ6": "<Box-Shadow für Elevation-Level 6>",
    "ElevationZ7": "<Box-Shadow für Elevation-Level 7>",
    "ElevationZ8": "<Box-Shadow für Elevation-Level 8>",
    "ElevationZ9": "<Box-Shadow für Elevation-Level 9>",
    "ElevationZ10": "<Box-Shadow für Elevation-Level 10>",
    "ElevationZ11": "<Box-Shadow für Elevation-Level 11>",
    "ElevationZ12": "<Box-Shadow für Elevation-Level 12>",
    "ElevationZ13": "<Box-Shadow für Elevation-Level 13>",
    "ElevationZ14": "<Box-Shadow für Elevation-Level 14>",
    "ElevationZ15": "<Box-Shadow für Elevation-Level 15>",
    "ElevationZ16": "<Box-Shadow für Elevation-Level 16>",
    "ElevationZ17": "<Box-Shadow für Elevation-Level 17>",
    "ElevationZ18": "<Box-Shadow für Elevation-Level 18>",
    "ElevationZ19": "<Box-Shadow für Elevation-Level 19>",
    "ElevationZ20": "<Box-Shadow für Elevation-Level 20>",
    "ElevationZ21": "<Box-Shadow für Elevation-Level 21>",
    "ElevationZ22": "<Box-Shadow für Elevation-Level 22>",
    "ElevationZ23": "<Box-Shadow für Elevation-Level 23>",
    "ElevationZ24": "<Box-Shadow für Elevation-Level 24>"
}