Marknaden
Priser
Logga inKom igång
FältguidenCSS och webb
CSS och webb

Bygg ett tema med CSS-variabler: ljust, mörkt och varumärkesfärger

Teman går fel när färger namnges efter hur de ser ut i stället för vad de gör. Namnge rollerna, peka dem mot en palett, så blir ljust läge, mörkt läge och ett andra varumärke några rader vardera.

GradientlyVerifierat Gradiently-konto·1 oktober 2026·5 minuters läsning
Omslag: Modal Compass · GR·5TEZ·Q9

Kortversionen

  • Ett tema med CSS-variabler fungerar bäst i två lager: palettvariabler som rymmer råa färger och semantiska variabler som beskriver vad varje färg är till för.
  • Komponenter ska bara läsa semantiska variabler som --color-text eller --color-surface, aldrig palettvärden direkt.
  • Mörkt läge blir då en fråga om att peka de semantiska variablerna mot andra palettvärden, under en mediefråga eller ett dataattribut.
  • Funktionen light-dark() och egenskapen color-scheme låter en deklaration rymma båda lägena i aktuella webbläsare.
  • Ett litet inbäddat skript i head som sätter det sparade temat innan sidan ritas förhindrar blixten av fel tema.
På den här sidan
Två lager: palett och rollerLägg till mörkt läge med CSS-variablerEn temaväxlare som inte blinkarVarumärkesteman bortom ljust och mörktHåll webben och dina designer på en palett

Ett tema med CSS-variabler är en uppsättning anpassade egenskaper, som --color-surface och --color-text, som varje komponent läser i stället för hårdkodade färger. För att byta tema ändrar du variablerna, oftast på :root eller på ett data-theme-attribut, och hela gränssnittet följer. Knepet som får det att skala är att dela variablerna i två lager: en palett av råa färger och semantiska roller som pekar mot den paletten.

Två lager: palett och roller

Palettvariabler namnges efter vad de är: --violet-600, --ink-900. Semantiska variabler namnges efter vad de gör: --color-accent, --color-text-muted. Komponenter läser bara den andra sorten. När mörkt läge kommer pekar du om rollerna och lämnar varje komponent orörd. Det är samma idé som designtokens, uttryckt direkt i CSS.

Palett--violet-600: #7c3aed

Vem som läser det

Bara rollagret

Ändras när

Varumärket designas om
Roll--color-accent: var(--violet-600)

Vem som läser det

Varje komponent

Ändras när

Temat eller läget ändras
Komponent

Exempel

--button-bg: var(--color-accent)

Vem som läser det

En komponent

Ändras när

En enskild komponent behöver en lokal vändning
LagerExempelVem som läser detÄndras när
Palett--violet-600: #7c3aedBara rollagretVarumärket designas om
Roll--color-accent: var(--violet-600)Varje komponentTemat eller läget ändras
Komponent--button-bg: var(--color-accent)En komponentEn enskild komponent behöver en lokal vändning
Komponentlagret är valfritt. Använd det bara där en komponent verkligen behöver skilja sig från rollen.
css
: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); }
Komponenter nämner aldrig violett eller bläck. Den enda regeln är det som gör temat utbytbart.
Det ljusa temats roller. En varm pappersbotten i stället för rent vitt gör att den violetta accenten känns lugnare.

Namnge roller som överlever en omdesign

Ett rollnamn ska fortfarande vara sant när färgerna ändras. --light-grey slutar vara ljus i mörkt läge, och --blue ljuger den dag varumärket blir grönt. Namnge jobbet och paret i stället, så att den som läser stilmallen härnäst vet vilken färg som hör ihop med vilken.

Namn som går sönder

  • --blue, --purple-button
  • --light-grey-bg
  • --white-text
  • --dark-border

Namn som håller

  • --color-accent, --color-on-accent
  • --color-surface
  • --color-text
  • --color-border

Lägg till mörkt läge med CSS-variabler

Mörkt läge pekar om rollerna. Respektera operativsystemets inställning som standard och låt ett data-theme-attribut åsidosätta den när läsaren väljer. Sätt också color-scheme, så att rullningslister, formulärkontroller och standardduken matchar.

css
: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);
}
De mörka värdena förekommer två gånger: en för systeminställningen och en för ett uttryckligt val. En preprocessor-mixin eller light-dark() tar bort upprepningen.
Det mörka temats roller. Accenten lyfts till en ljusare violett, eftersom det ljusa lägets violett är för mörk för att läsas på en nästan svart botten.

Mörkt läge är inte ett inverterat ljust läge. Ytor blir ljusare ju högre de ligger, accenter ljusnar och skuggor viker för kantlinjer. Design för mörkt läge och gradienter för mörkt läge tar upp den visuella sidan.

Genvägen light-dark()

Aktuella webbläsare stöder light-dark(), som tar ett ljust värde och ett mörkt värde och väljer ett utifrån elementets color-scheme. Sätt color-scheme: light dark på roten för att följa systemet, eller tvinga ett med attributet, så blir varje roll en enda rad: --color-bg: light-dark(var(--paper-50), var(--night-950)). Behåll den längre formen om du måste stödja webbläsare från före 2024.

En temaväxlare som inte blinkar

Om det sparade valet tillämpas efter att sidan ritats ser läsare som valt mörkt en vit blixt vid varje laddning. Sätt attributet i ett pyttelitet inbäddat skript i head, innan någon stilmall målar kroppen.

html
<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>
Körs före första ritningen. Växlingsknappen behöver sedan bara sätta dataset.theme och spara värdet i localStorage.
  1. 1

    Erbjud tre val

    Ljust, mörkt och system. Att ta bort attributet ger kontrollen tillbaka till prefers-color-scheme.

  2. 2

    Spara bara uttryckliga val

    Lagra light eller dark; ta bort nyckeln för system, så att en senare ändring i operativsystemet respekteras.

  3. 3

    Undvik övergångar vid laddning

    Om färger har övergångar, aktivera övergången först efter första ritningen, annars animeras sidan från ljus till mörk medan den laddas.

Varumärkesteman bortom ljust och mörkt

Samma två lager hanterar flera varumärken i en kodbas. Varje varumärke ger sina egna palett- och rollvärden under ett data-brand-attribut, och lägena fungerar fortfarande ovanpå. Med color-mix() kan du härleda hovringslägen och toner från en accent per varumärke, som visas i color-mix() i CSS.

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); }
Gradienter kan också vara tokens. Lagra hela värdet i en variabel så ändras heron med varumärket.
De två herotokens från koden ovan. Samma struktur, samma vinkel, olika varumärke.

Eftersom anpassade egenskaper ärvs behöver ett tema inte täcka hela sidan. Lägg data-theme="dark" på en sektion, som ett kampanjband eller en sidfot, så läser allt inuti den de mörka rollerna medan resten av sidan förblir ljus. Skriv den mörka väljaren som [data-theme="dark"] i stället för :root[data-theme="dark"] om du vill att det ska fungera, och sätt color-scheme på sektionen också.

Gradienter övergår inte av sig själva

Att ändra en gradientvariabel byter bakgrunden direkt. För att animera mellan två gradienter, registrera färgstoppen med @property, förklarat i CSS @property.

Håll webben och dina designer på en palett

Ett tema i CSS är bara halva ett varumärke. Samma färger ska finnas i dina sociala inlägg, presentationer och e-postmeddelanden. Gradiently varumärkeskit rymmer dina paletter, logotyper och rubrik- och brödtypsnitt, och Designer tillämpar det när den lägger ut en design, så att inlägget du gör på måndagen använder samma accent som din webbplats. Om du fortfarande väljer färgerna, börja med hur du väljer varumärkesfärger.

Fråga Designern

Beskriv vad du behöver, så skapar Gradiently AI det, på din Mark.

Testa Designern

Vanliga frågor

Hur gör jag ett tema med CSS-variabler?

Definiera palettvariabler med råa färger och sedan semantiska variabler som --color-bg som pekar mot dem. Komponenter läser bara de semantiska, och teman pekar om dem.

Hur lägger jag till mörkt läge med CSS-variabler?

Åsidosätt de semantiska variablerna inuti @media (prefers-color-scheme: dark) och under en [data-theme="dark"]-väljare för läsare som väljer det.

Hur stoppar jag att temat blinkar vid sidladdning?

Läs det sparade temat i ett litet inbäddat skript i head och sätt attributet innan stilmallen ritar sidan.

Vad gör light-dark() i CSS?

Den returnerar sitt första värde i ljust läge och sitt andra i mörkt läge, utifrån elementets color-scheme. Den fungerar i aktuella större webbläsare.

Kan jag lagra en gradient i en CSS-variabel?

Ja. Lagra hela gradienten som värde och använd den i background. För att animera mellan gradienter, registrera stoppen med @property.

Dela den här guiden

Skriven av GradientlyVerifierat Gradiently-konto

Teamet bakom Gradiently, ett designverktyg byggt kring Marks: levande gradienter som får allt du gör att kännas som ditt.

Se vår profil

På den här sidan

Två lager: palett och rollerLägg till mörkt läge med CSS-variablerEn temaväxlare som inte blinkarVarumärkesteman bortom ljust och mörktHåll webben och dina designer på en palett

Dela den här guiden

Nästa i CSS och webb

CSS-gradientgenerator: skriv gradienter för hand eller med verktyg

Läs vidare

Alla guider om CSS och webb
CSS och webb

Designtokens: en enda källa för färg och typografi

4 minuters läsning

En varumärkesfärg som finns i fyrtio filer kommer att glida isär. En token bor på ett ställe och varje plattform läser från den. Så strukturerar du designtokens, namnger dem så att de håller och levererar dem till kod och designverktyg.

Bakgrunder

Design för mörkt läge: bakgrunder, färg och kontrast

5 minuters läsning

Mörkt läge är inte ljust läge inverterat. Ytor, text, accenter och gradienter behöver egna värden, och reglerna skiljer sig från dem du känner.

CSS och webb

color-mix() i CSS: blanda färger i webbläsaren

5 minuters läsning

color-mix() låter webbläsaren göra färgmatematiken du förr gjorde i en preprocessor eller på känn. Välj rätt färgrum så kan en varumärkesfärg ge en hel palett av toner, nyanser och genomskinliga versioner.

Hitta looken som bara är din.

Varje Mark är en levande bakgrund med en enda ägare. Prova en ledig Mark och säkra din när det känns rätt.

Börja designa

Kontrollera ett certifikat

Skriv ett certifikatnummer eller en Marks kod för att se vem som äger den.

Fungerar med ChatGPT och Claude

Be din AI om en design. Den skapar den i din Mark, redo att redigera.

ChatGPTClaude
Så ansluter du

Produkt

  • Marknaden
  • Utforska
  • Priser
  • Certifikat

Lär dig

  • Fältguiden
  • Hjälpcenter
  • Nyheter

Utvecklare

  • Översikt
  • ChatGPT och Claude
  • API-referens
  • API-nycklar

Företaget

  • Om oss
  • Kontakta oss
  • Logga in

Juridik

  • Villkor
  • Integritet
  • Återbetalningar
  • Mark-skydd
  • Cookies
  • Alla policyer
Rör dig över bokstäverna. Var och en bär en riktig Mark.Tryck på en bokstav för att se dess Mark.Ett namn. Tio Marks inuti.
© 2026 Gradiently