CSS Custom Properties & Teme Dark Mode Fără JavaScript
Variabilele native CSS (Custom Properties) au revoluționat arhitectura front-end, eliminând dependența de preprocesoare precum Sass sau Less. Înțelege cum funcționează cascadarea valorilor, cum eviți efectul de clipire (FOIT) și cum construiești un sistem complet Dark/Light Mode bazat pe preferințele utilizatorului.
$color) sunt compilate static la build-time și devin valori fixe de pixeli sau hexazecimale în fișierul final. În schimb, CSS Custom Properties (--color) trăiesc în arborele DOM în timp real, se recalculează automat la runtime, moștenesc valorile părinților și pot fi modificate instant prin media queries sau pseudo-clase.
1. Fundamentele: Declarare, Utilizare și Valori Fallback
Variabilele CSS încep obligatoriu cu două liniuțe (--) și sunt case-sensitive (--culoare-text este diferită de --Culoare-Text):
/* 1. Declarare globala pe pseudo-clasa :root (cel mai inalt nivel din DOM) */
:root {
--fundal-pagina: #f8fafc;
--text-principal: #0f172a;
--text-secundar: #475569;
--culoare-brand: #2563eb;
--raza-card: 8px;
}
/* 2. Consumarea variabilei in componente */
.card {
background-color: var(--fundal-pagina);
color: var(--text-principal);
border-radius: var(--raza-card);
border: 1px solid var(--culoare-border, #e2e8f0); /* Fallback integrat */
}
Puterea fallback-ului (valoare de rezervă): Al doilea parametru al funcției var(--nume, fallback) este utilizat automat dacă variabila nu a fost definită anterior în arborele DOM.
2. Trecerea la Dark Mode Automat cu prefers-color-scheme
Sistemele de operare moderne (Windows, macOS, Android, iOS) permit utilizatorului să selecteze tema întunecată la nivel de sistem. Browserul transmite această preferință prin intermediul interogării media prefers-color-scheme:
/* Paleta de baza (Light Mode implicit) */
:root {
--bg-app: #ffffff;
--text-app: #111827;
--border-app: #e5e7eb;
color-scheme: light dark; /* Anunta browserul ca suportam ambele moduri */
}
/* Suprascrierea inteligenta cand utilizatorul are Dark Mode activ in OS */
@media (prefers-color-scheme: dark) {
:root {
--bg-app: #0f172a;
--text-app: #f8fafc;
--border-app: #1e293b;
}
}
body {
background-color: var(--bg-app);
color: var(--text-app);
transition: background-color .25s ease, color .25s ease;
}
3. Comutator Manual de Temă (User Override cu data-theme)
Deși respectarea setărilor OS este obligatorie pentru accesibilitate, utilizatorii doresc adesea un buton manual de comutare în interfață. Cea mai scalabilă arhitectură este utilizarea unui atribut de date pe elementul <html>:
/* Setari implicite (Tema Light) */
:root {
--bg-app: #ffffff;
--text-app: #1c2530;
--accent-app: #d6472e;
}
/* Daca sistemul prefera dark SI utilizatorul nu a fortat light */
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--bg-app: #0e2a47;
--text-app: #efe7d6;
--accent-app: #e8b339;
}
}
/* Cand utilizatorul forteaza explicit modul intunecat din buton */
[data-theme="dark"] {
--bg-app: #0e2a47;
--text-app: #efe7d6;
--accent-app: #e8b339;
}
Cum eviți clipirea albă (Flash of White / FOIT) la încărcare:
Dacă salvezi preferința utilizatorului în localStorage, citește-o printr-un micro-script inline plasat direct în interiorul etichetei <head>, înainte de randarea tagului <body>:
<head>
<!-- Previne Flash of Incorrect Theme (Zero milisecunde de ecran alb) -->
<script>
const temaSalvata = localStorage.getItem('user-theme');
if (temaSalvata) {
document.documentElement.setAttribute('data-theme', temaSalvata);
}
</script>
</head>
4. Inovația CSS Color Module Level 4: Funcția color-mix()
În trecut, pentru a obține o nuanță transparentă sau mai deschisă a unei culori dinamice, aveai nevoie de hack-uri RGB separate (de exemplu --color-rgb: 214, 71, 46 urmat de rgba(var(--color-rgb), 0.2)). Astăzi, specificația W3C include funcția nativă color-mix():
:root {
--brand: #2563eb;
}
.buton-secundar {
/* Amesteca 15% culoare de brand cu 85% transparenta */
background: color-mix(in srgb, var(--brand) 15%, transparent);
color: var(--brand);
border: 1px solid color-mix(in srgb, var(--brand) 40%, transparent);
}
.buton-secundar:hover {
/* Amesteca culoarea de brand cu 10% negru pentru efect de apasare */
background: color-mix(in srgb, var(--brand) 25%, #000);
}
5. Reguli de Aur pentru Performanță cu Variabile CSS
- Declară variabilele globale doar pe
:root: Evită să declari zeci de variabile pe selectorul universal* { --var: 1; }, deoarece forțează motorul CSS să recalculeze stilurile pentru fiecare nod din pagină; - Folosește variabile locale pentru variații de componente: Variabilele pot fi suprascrise contextual. De exemplu, un buton de alertă poate doar redefini
--btn-bg: #dc2626;fără a rescrie toate regulile de padding sau font; - Păstrează contrastul accesibil (WCAG AA): În modul Dark, evită negrul absolut (
#000000) pentru fundaluri mari, deoarece creează ochiului un contrast prea dur și provoacă oboseală optică (haloing). Folosește nuanțe precum#0f172asau#121820.
Specificații W3C și Referințe Consultate:
- W3C CSS Custom Properties for Cascading Variables Module Level 1: w3.org/TR/css-variables-1/
- W3C CSS Color Module Level 4 (color-mix function): w3.org/TR/css-color-4/#color-mix
- W3C Media Queries Level 5 (prefers-color-scheme): w3.org/TR/mediaqueries-5/#prefers-color-scheme