Eine Website entscheidet sich auf zwei Arten zwischen hell und dunkel: der Systempräferenz des Besuchers oder einer expliziten Wahl, die die Website für diesen Besucher speichert. EmDash-Komponenten lesen beide Signale über eine Konvention am <html>-Element. Diese Seite beschreibt diese Konvention, wie man einem Bildfeld eine dunkle Variante gibt und wie man sie mit der Image-Komponente aus emdash/ui rendert.
Theme-Konvention
Komponenten und Templates verwenden diese zwei Signale in dieser Reihenfolge:
- Eine
dark- oderlight-Klasse auf<html>legt das Schema fest. Die Klasse gewinnt über die Systempräferenz. - Ohne Klasse folgt das Schema der
prefers-color-scheme-Media-Query.
Die mitgelieferten Templates speichern eine explizite Wahl in einem theme-Cookie und wenden sie vor dem ersten Paint mit einem Inline-Skript in <head> an. Das folgende Skript liest den Cookie und setzt die Klasse, und tut nichts, wenn keine Wahl gespeichert ist:
<script is:inline>
(function () {
var c = document.cookie;
var i = c.indexOf("theme=");
var theme = i >= 0 ? c.slice(i + 6).split(";")[0] : null;
if (theme === "dark" || theme === "light") {
document.documentElement.classList.add(theme);
}
})();
</script>
Definieren Sie Farben einmal mit light-dark() und lassen Sie die Klasse das Schema festlegen:
:root {
color-scheme: light dark;
--color-bg: light-dark(#ffffff, #0d0d0d);
--color-text: light-dark(#1a1a1a, #ededed);
}
:root.light {
color-scheme: light;
}
:root.dark {
color-scheme: dark;
}
Eine Website ohne Theme-Umschalter braucht kein Skript: Lassen Sie <html> ohne Klasse und die Systempräferenz gilt.
Dunkle Bildvarianten
Ein Bildfeld kann ein zweites Bild für dunkle Farbschemata enthalten. Redakteure wählen es neben dem Primärbild aus, und die Image-Komponente zeigt das an, das zum Schema des Besuchers passt.
Slot an einem Feld aktivieren
Der Slot ist standardmäßig deaktiviert. Schalten Sie ihn pro Feld ein, entweder im Admin oder in einer Seed-Datei.
Im Admin öffnen Sie Content Types, bearbeiten das Bildfeld und aktivieren Dark mode variant.
In einer Seed-Datei setzen Sie die darkVariant-Widget-Option am Feld:
{
"slug": "featured_image",
"label": "Featured Image",
"type": "image",
"options": { "darkVariant": true }
}
Variante im Editor auswählen
-
Öffnen Sie einen Eintrag und wählen Sie das Primärbild wie gewohnt aus.
-
Klicken Sie auf Add dark mode variant unter dem Bild und wählen Sie die dunkle Variante aus der Mediathek.
-
Speichern Sie den Eintrag.
Die Variante wird im Feldwert als darkVariant gespeichert. Das Entfernen des Primärbilds entfernt auch die Variante; das Ersetzen des Primärbilds behält die Variante bei, bis Sie sie ersetzen oder entfernen.
Variante rendern
Die Image-Komponente rendert beide Bilder, wenn der Wert eine darkVariant enthält, und zeigt das passende mit CSS an. Nichts ändert sich im Template:
---
import { Image } from "emdash/ui";
import { getEmDashEntry } from "emdash";
const { entry: post } = await getEmDashEntry("posts", Astro.params.slug);
---
{post?.data.featured_image && <Image image={post.data.featured_image} priority />}
Die Ausgabe enthält zwei <img>-Elemente. Das Primärbild bekommt die Klasse emdash-image--light und die Variante bekommt emdash-image--dark. Beide verwenden den alt-Text, Breiten- und Höhenüberschreibungen und Ladeattribute des Primärbilds. Jedes behält seine eigene Platzhalterfarbe.
Eine id, die Sie übergeben, bleibt am Primärbild; die Variante bekommt dieselbe id mit einem --dark-Suffix, also ergibt id="hero" hero und hero--dark.
Wenn das dunkle Bild von woanders kommt, zum Beispiel einem zweiten Bildfeld, übergeben Sie es explizit:
<Image image={post.data.hero} darkVariant={post.data.hero_dark} />
Ladeverhalten
Beide Bilder sind standardmäßig lazy. Browser laden kein lazy Bild, das mit display: none ausgeblendet ist, sodass ein Besucher nur die Variante für sein Schema herunterlädt und die andere geladen wird, wenn sich das Schema ändert.
Mit priority erhalten beide Bilder loading="eager" und fetchpriority="high", und beide werden in jedem Schema heruntergeladen. Das Theme wird im Browser entschieden, sodass der Server nicht wissen kann, welche Variante ein Besucher sehen wird. Verwenden Sie priority für das eine Bild über dem Fold und lassen Sie andere Bilder lazy.
Eine andere Theme-Konvention verwenden
Das mitgelieferte CSS versteckt die Variante, die nicht zum Schema passt. Seine Selektoren verwenden :where() am <html>-Teil, sodass jede Ihrer Regeln, die <html> mit einer Klasse oder einem Attribut anspricht, gewinnt.
Wenn Ihr Umschalter ein Attribut wie data-theme setzt, ist die kürzeste Lösung, auch die dark- und light-Klassen im selben Codepfad zu setzen. Andernfalls überschreiben Sie die vier Fälle in Ihrem eigenen Stylesheet:
:root[data-theme="dark"] .emdash-image--light,
:root[data-theme="light"] .emdash-image--dark {
display: none;
}
:root[data-theme="dark"] .emdash-image--dark,
:root[data-theme="light"] .emdash-image--light {
display: block;
}
Passen Sie den display-Wert an das an, was Ihr Stylesheet Bildern anderswo gibt, zum Beispiel inline, wenn Sie img nicht auf block zurücksetzen.