webroad.online
  1. 1Web
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Unelte
  8. 8React
  9. 9State management
  10. 10Next.js
  11. 11Formulare
  12. 12Date și backend
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Animații
  16. 16Testare
  17. 17Arhitectură
Tailwind CSS · Lecția 3 din 6

Teme și design tokens

@theme, tokens semantici, light/dark cu variabile CSS și toggle manual.

Actualizat

Ce este o temă

O temă e setul de decizii vizuale ale unui produs: culori, fonturi, raze, umbre, spațieri. Într-un proiect bine construit, aceste decizii sunt centralizate în design tokens — variabile cu nume — iar componentele folosesc doar token-urile.

Rezultatul: schimbi brandul, adaugi dark mode sau un al doilea brand dintr-un singur fișier, fără să atingi componentele.

Tokens, nu culori hardcodate

Greșeala clasică: bg-blue-600 împrăștiat prin 200 de fișiere. Schimbi brandul → schimbi 200 de fișiere.

Corect: definești design tokens semantice (ce rol are culoarea, nu ce nuanță e) și le folosești peste tot.

primitive:  blue-600, stone-100          → paleta brută
semantic:   accent, bg, surface, muted   → ce folosește UI-ul

@theme — tokens care devin clase

@import "tailwindcss";

@theme {
  --color-accent: #1f5fbf;
  --font-display: "IBM Plex Sans", sans-serif;
  --radius-card: 0.75rem;
}

Fiecare variabilă din namespace-ul potrivit generează clase: --color-accent → bg-accent, text-accent, border-accent/50; --font-display → font-display; --radius-card → rounded-card.

Namespace Clase
--color-* bg-*, text-*, border-*, fill-*…
--font-* font-*
--text-* text-* (mărimi)
--spacing baza pentru p-*, m-*, gap-*
--radius-* rounded-*
--shadow-* shadow-*
--breakpoint-* sm:, md:…

Light / dark cu variabile CSS

Pattern-ul folosit chiar în aplicația asta:

:root {
  --bg: #f7f6f3;
  --fg: #1f1e1c;
  --accent: #1f5fbf;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #141414;
    --fg: #e9e7e2;
    --accent: #6ea4f0;
  }
}

@theme inline {
  --color-bg: var(--bg);
  --color-fg: var(--fg);
  --color-accent: var(--accent);
}

@theme inline = clasa folosește direct var(--bg), deci se schimbă când variabila se schimbă. Componentele scriu doar bg-bg text-fg — nu au nevoie de dark: deloc.

Toggle manual (buton de temă)

Implicit, dark: urmează sistemul. Pentru un buton care forțează tema:

@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));

[data-theme=dark] {
  --bg: #141414;
  --fg: #e9e7e2;
}

Pui data-theme="dark" pe <html> (salvat în cookie/localStorage, aplicat înainte de hidratare ca să nu clipească).

Light / dark / sistem, fără „flash”

Un toggle real are trei opțiuni: luminos, întunecat și „ca sistemul”. Problema clasică: pagina se randează pe server fără să știe alegerea userului → apare o fracțiune de secundă în tema greșită (flash), apoi JS-ul o corectează.

Unde salvezi alegerea Cum eviți flash-ul
cookie serverul citește cookie-ul și pune direct data-theme pe <html> — zero flash (pagina devine dinamică)
localStorage un script mic, inline în <head>, setează data-theme înainte să se deseneze pagina — ce face librăria next-themes
/* „sistem” = fără atribut → urmează prefers-color-scheme */
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));

@media (prefers-color-scheme: dark) {
  :root:not([data-theme=light]) { --bg: #141414; --fg: #e9e7e2; }
}
[data-theme=dark] { --bg: #141414; --fg: #e9e7e2; }

Adaugă și color-scheme: light dark pe :root — scrollbar-urile și controalele native (input, select) se adaptează automat.

Mai multe teme / branduri

Același mecanism: [data-theme=ocean] { --accent: ... }. Componentele nu se schimbă deloc.

Reguli

  1. Componentele folosesc doar tokens semantici (bg-surface, text-muted), nu bg-stone-100.
  2. Puține tokens, bine numite: bg, surface, fg, muted, line, accent, success, danger.
  3. Verifică contrastul în ambele teme.

Pe scurt

  • Tokens semantici (bg, surface, accent), nu culori brute în componente.
  • @theme creează clase; @theme inline + variabile CSS = teme care se schimbă la runtime.
  • Dark mode și branduri multiple = alte valori pentru aceleași variabile.

Surse oficiale

Exerciții

Ți-a fost utilă pagina?

Un click — fără cont.