Kort fortalt
- Et tema med CSS-variabler virker bedst i to lag: paletvariabler, der rummer rå farver, og semantiske variabler, der beskriver, hvad hver farve bruges til.
- Komponenter bør kun læse semantiske variabler som --color-text eller --color-surface, aldrig paletværdier direkte.
- Mørk tilstand er så et spørgsmål om at pege de semantiske variabler mod andre paletværdier, under en media query eller en data-attribut.
- Funktionen light-dark() og egenskaben color-scheme lader én deklaration rumme begge tilstande i nuværende browsere.
- Et lille inline-script i head, der sætter det gemte tema, før siden males, forhindrer et glimt af det forkerte tema.
På denne side
Et tema med CSS-variabler er et sæt custom properties som --color-surface og --color-text, som hver komponent læser i stedet for hårdkodede farver. For at ændre temaet ændrer du variablerne, som regel på :root eller på en data-theme-attribut, og hele brugerfladen følger med. Tricket, der får det til at skalere, er at dele variablerne i to lag: en palet af rå farver og semantiske roller, der peger mod den palet.
To lag: palet og roller
Paletvariabler navngives efter, hvad de er: --violet-600, --ink-900. Semantiske variabler navngives efter, hvad de gør: --color-accent, --color-text-muted. Komponenter læser kun den anden slags. Når mørk tilstand kommer, peger du rollerne om og rører ikke en eneste komponent. Det er den samme idé som design tokens, udtrykt direkte i CSS.
--violet-600: #7c3aedHvem læser det
Ændrer sig, når
--color-accent: var(--violet-600)Hvem læser det
Ændrer sig, når
Eksempel
--button-bg: var(--color-accent)Hvem læser det
Ændrer sig, når
:root {
/* Palette: raw values, named for what they are */
--paper-50: #faf8f5;
--paper-100: #f1ede6;
--ink-900: #14121f;
--ink-700: #3d3a4f;
--ink-500: #6b6880;
--violet-600: #6d28d9;
--violet-300: #c4b5fd;
--night-950: #0d0b16;
--night-900: #17142a;
--night-800: #221e3a;
/* Roles: what each colour is for (light mode) */
--color-bg: var(--paper-50);
--color-surface: var(--paper-100);
--color-text: var(--ink-900);
--color-text-muted: var(--ink-500);
--color-border: color-mix(in oklab, var(--ink-900) 12%, transparent);
--color-accent: var(--violet-600);
--color-on-accent: #ffffff;
}
body { background: var(--color-bg); color: var(--color-text); }
.card { background: var(--color-surface); border: 1px solid var(--color-border); }
.button { background: var(--color-accent); color: var(--color-on-accent); }Rollenavne, der overlever et redesign
Et rollenavn bør stadig være sandt, efter farverne ændrer sig. --light-grey holder op med at være lys i mørk tilstand, og --blue lyver den dag, brandet bliver grønt. Navngiv i stedet jobbet og parringen, så den, der læser stylesheetet næste gang, ved, hvilken farve der hører til hvad.
Navne, der går i stykker
--blue,--purple-button--light-grey-bg--white-text--dark-border
Navne, der holder
--color-accent,--color-on-accent--color-surface--color-text--color-border
Tilføj mørk tilstand med CSS-variabler
Mørk tilstand peger rollerne om. Respektér styresystemets indstilling som standard, og lad en data-theme-attribut tilsidesætte den, når læseren vælger. Sæt også color-scheme, så rullebjælker, formularfelter og standardlærredet passer.
:root { color-scheme: light; }
/* Follow the system unless the reader picked light */
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
color-scheme: dark;
--color-bg: var(--night-950);
--color-surface: var(--night-900);
--color-text: #f2f0fa;
--color-text-muted: #a5a1bd;
--color-border: color-mix(in oklab, #ffffff 12%, transparent);
--color-accent: var(--violet-300);
--color-on-accent: var(--ink-900);
}
}
/* The reader picked dark explicitly */
:root[data-theme="dark"] {
color-scheme: dark;
--color-bg: var(--night-950);
--color-surface: var(--night-900);
--color-text: #f2f0fa;
--color-text-muted: #a5a1bd;
--color-border: color-mix(in oklab, #ffffff 12%, transparent);
--color-accent: var(--violet-300);
--color-on-accent: var(--ink-900);
}light-dark() fjerner gentagelsen.Mørk tilstand er ikke omvendt lys tilstand. Overflader bliver lysere, jo højere de hæver sig, accenter lysnes, og skygger viger for kanter. Design af mørk tilstand og gradienter i mørk tilstand dækker den visuelle side.
Genvejen light-dark()
Nuværende browsere understøtter light-dark(), som tager en lys og en mørk værdi og vælger den ene ud fra elementets color-scheme. Sæt color-scheme: light dark på roden for at følge systemet, eller gennemtving det ene med attributten, så bliver hver rolle til én linje: --color-bg: light-dark(var(--paper-50), var(--night-950)). Behold den længere form, hvis du skal understøtte browsere fra før 2024.
En temaomskifter, der ikke blinker
Hvis det gemte valg anvendes, efter siden er gengivet, ser læsere, der valgte mørk, et hvidt glimt ved hver indlæsning. Sæt attributten i et lille inline-script i head, før noget stylesheet maler body.
<head>
<script>
(function () {
var saved = localStorage.getItem("theme");
if (saved === "light" || saved === "dark") {
document.documentElement.dataset.theme = saved;
}
})();
</script>
<link rel="stylesheet" href="/styles.css">
</head>dataset.theme og gemme værdien i localStorage.- 1
Tilbyd tre valg
Lys, mørk og system. Når attributten fjernes, går styringen tilbage til
prefers-color-scheme. - 2
Gem kun eksplicitte valg
Gem
lightellerdark. Slet nøglen for system, så en senere ændring i styresystemet respekteres. - 3
Undgå overgange ved indlæsning
Hvis farver har overgange, så slå overgangen først til efter første maling, ellers animerer siden fra lys til mørk, mens den indlæses.
Brandtemaer ud over lys og mørk
De samme to lag håndterer flere brands i én kodebase. Hvert brand leverer sin egen palet og sine egne rolleværdier under en data-brand-attribut, og tilstandene virker stadig ovenpå. Med color-mix() kan du udlede hover-tilstande og lysere nuancer af én accent pr. brand, som vist i color-mix() i CSS.
[data-brand="harbour"] {
--color-accent: #0f766e;
--gradient-hero: linear-gradient(150deg, #042f2e 0%, #0f766e 55%, #5eead4 100%);
}
[data-brand="ember"] {
--color-accent: #c2410c;
--gradient-hero: linear-gradient(150deg, #431407 0%, #c2410c 55%, #fdba74 100%);
}
.button:hover { background: color-mix(in oklab, var(--color-accent), black 12%); }
.hero { background: var(--gradient-hero); }Fordi custom properties nedarves, behøver et tema ikke dække hele siden. Sæt data-theme="dark" på én sektion, for eksempel et reklamebånd eller en footer, og alt indeni læser de mørke roller, mens resten af siden forbliver lys. Skriv den mørke selektor som [data-theme="dark"] frem for :root[data-theme="dark"], hvis du vil have det til at virke, og sæt også color-scheme på sektionen.
Hold nettet og dine designs på én palet
Et tema i CSS er kun det halve af et brand. De samme farver skal optræde i dine opslag på sociale medier, dine præsentationer og mails. brandkittet i Gradiently rummer dine paletter, logoer og overskrifts- og brødtekstskrifttyper, og Designer anvender det, når den lægger et design ud, så opslaget, du laver mandag, bruger den samme accent som dit site. Er du stadig i gang med at vælge de farver, så start med sådan vælger du brandfarver.
Spørgsmål, folk stiller
Hvordan laver jeg et tema med CSS-variabler?
Definer paletvariabler med rå farver, og så semantiske variabler som --color-bg, der peger mod dem. Komponenter læser kun de semantiske, og temaer peger dem om.
Hvordan tilføjer jeg mørk tilstand med CSS-variabler?
Tilsidesæt de semantiske variabler inde i @media (prefers-color-scheme: dark) og under en [data-theme="dark"]-selektor til læsere, der vælger det.
Hvordan forhindrer jeg, at temaet blinker ved indlæsning?
Læs det gemte tema i et lille inline-script i head, og sæt attributten, før stylesheetet maler siden.
Hvad gør light-dark() i CSS?
Den returnerer sin første værdi i lys tilstand og sin anden i mørk tilstand, ud fra elementets color-scheme. Den virker i nuværende store browsere.
Kan jeg gemme en gradient i en CSS-variabel?
Ja. Gem hele gradienten som værdien, og brug den i background. For at animere mellem gradienter skal du registrere stoppene med @property.
Skrevet af Gradiently
Holdet bag Gradiently, et designværktøj bygget om Marks: levende gradienter, der får alt, du designer, til at ligne dig.
Se vores profil