Automatischer Dark Mode für Drawio Diagramme mittels CSS Filter

In meinem neuesten Blogpost “Nginx HTTP/3 Proxyserver zeigt Inhalte vom falschen Virtual Host” habe ich ein Diagramm von Diagrams.net / Drawio eingebunden, das eine SVG-Datei ist.

Wenn man sein Diagramm aus Draw.io exportiert, kann man wählen, ob man für die exportierte Grafik ein helles oder ein dunkles Farbthema anwenden will. Ich wähle hier normalerweise das helle, damit sich das Diagramm gut in das helle Default-Theme von thomas-leister.de einfügt. Aber wie gehe ich damit in der dunklen Variante meines Blogs um? Benutzer sehen automatisch das dunkle Theme, wenn sie ihr Betriebssystem entsprechend eingestellt haben. Ich habe mich gefragt, ob es nicht einen einfachen Weg gibt, um die hellen SVG Grafiken bei Bedarf in dunkle Varianten umzuwandeln. Schließlich kennt CSS ja mittlerweile filter, oder?

Zum Glück habe ich ziemlich schnell eine einfache Lösung für das Problem finden können: “One line - Dark Mode using CSS”. Und das ist der Trick, den ich gefunden habe:

filter: invert(1) hue-rotate(180deg);

Diese CSS-Zeile invertiert zunächst alle Farben (also von hell nach dunkel und umgekehrt). Dabei wird schwarz in weiß umgewandelt (und umgekehrt), aber Farben werden auch umgekehrt. Das ist nicht beabsichtigt. Deshalb werden über ein hue-rotate Farbige Inhalte wieder zurückkonvertiert.

In meinem CSS Stylesheet meines Blogs habe ich folgendes implementiert:

@media (prefers-color-scheme: dark) {
    /* 
    * Invert colors for SVG diagrams
    */
    figure.diagram  img {
        filter: invert(1) hue-rotate(180deg);
    }
}

Von der Umwandlung sind nur Grafiken betroffen, die sich in einem <figure> HTML element der Klasse diagram befinden - und nur dann, wenn der Benutzer ein dunkles Theme in seinen Betriebssystemeinstellungen gewählt hat.

Wenn ich nun in einem Blogeintrag eine SVG-Zeichnung einbinden will, mache ich das über den folgenden Shortcode:

{{< figure src="images/my-drawing.drawio.svg" caption="My description" class="diagram" >}}

Und kann das Ergebnis aussehen (oben im Dark Mode - unten im Light Mode):

Example screenshot of a diagram on my blog