Lekcja 29
Zmienne CSS i design tokens
Zmienne CSS pozwalają nazwać wartości i używać ich w wielu miejscach. Design tokens idą krok dalej: tworzą wspólny język dla kolorów, odstępów, promieni, cieni, typografii i stanów interfejsu.
Cele lekcji
Po ukończeniu tej lekcji będziesz umieć:
- definiować zmienne CSS przez custom properties,
- używać funkcji
var()z wartością awaryjną, - odróżniać tokeny bazowe od tokenów semantycznych,
- budować proste skale odstępów, promieni i cieni,
- nadpisywać tokeny lokalnie w komponencie,
- projektować tokeny tak, aby wspierały spójny system UI.
Kontekst praktyczny
W większym projekcie te same wartości pojawiają się w wielu komponentach. Bez tokenów szybko powstaje kilkanaście podobnych odcieni, promieni i cieni. Z czasem trudno ocenić, która wartość jest aktualna, a która została po jednorazowej poprawce.
#2563eb, używasz --color-primary albo --color-action-bg.Custom properties
Zmienne CSS definiuje się jako custom properties, czyli właściwości zaczynające się od dwóch myślników. Najczęściej zapisuje się je w :root, aby były dostępne globalnie.
:root {
--color-primary: #2563eb;
--space-md: 1rem;
--radius-md: .75rem;
}
.button {
padding: var(--space-md);
border-radius: var(--radius-md);
background: var(--color-primary);
}
Custom properties dziedziczą się podobnie jak wiele zwykłych właściwości CSS. To daje dużą elastyczność, ale wymaga konsekwentnych nazw.
var() i fallback
Funkcja var() pobiera wartość zmiennej. Możesz dodać fallback, czyli wartość awaryjną, która zostanie użyta, gdy zmienna nie istnieje.
.alert {
color: var(--alert-text, #7f1d1d);
background: var(--alert-bg, #fee2e2);
}
Fallback nie zastępuje dobrej organizacji tokenów. Jest zabezpieczeniem, a nie sposobem na ukrywanie chaosu w nazwach.
Tokeny bazowe
Token bazowy opisuje surową wartość skali: konkretny kolor, odstęp, promień albo cień. Jest blisko systemu wizualnego, ale nie zawsze mówi, gdzie powinien być użyty.
:root {
--blue-600: #2563eb;
--green-600: #16a34a;
--space-4: 1rem;
--radius-3: .75rem;
}
Tokeny bazowe są przydatne jako fundament, ale w komponentach często lepiej używać tokenów semantycznych.
Tokeny semantyczne
Token semantyczny opisuje rolę wartości w interfejsie. Dzięki temu komponent nie musi wiedzieć, jaki dokładnie odcień reprezentuje akcję, sukces albo powierzchnię.
:root {
--color-action-bg: var(--blue-600);
--color-success-bg: #dcfce7;
--color-surface-default: #ffffff;
--color-border-subtle: #e2e8f0;
}
Gdy zmieniasz brand albo tryb kolorystyczny, semantyka pozwala wymienić wartości bez przepisywania każdego komponentu.
Skale odstępów i promieni
Design tokens najlepiej działają jako małe skale. Nie potrzebujesz dwudziestu prawie identycznych odstępów. Potrzebujesz kilku nazwanych wartości, które powtarzają się konsekwentnie.
:root {
--space-xs: .25rem;
--space-sm: .5rem;
--space-md: 1rem;
--space-lg: 1.5rem;
--radius-sm: .5rem;
--radius-md: .75rem;
}
Skala nie musi być idealna matematycznie. Ważniejsze, żeby była mała, czytelna i stosowana konsekwentnie.
Lokalne nadpisanie
Custom properties możesz nadpisać lokalnie w komponencie. To dobry wzorzec dla wariantów, bo komponent zachowuje tę samą strukturę, a zmienia tylko zestaw tokenów.
.status-card {
--status-bg: #eff6ff;
--status-border: #bfdbfe;
background: var(--status-bg);
border-color: var(--status-border);
}
.status-card--success {
--status-bg: #f0fdf4;
--status-border: #86efac;
}
Taki komponent jest łatwiejszy do rozszerzania niż kilka wariantów kopiujących pełne zestawy właściwości.
Demo design tokens
Demo pokazuje jeden komponent korzystający z tych samych nazw tokenów. Wariant domyślny i sukcesu różnią się tylko wartościami tokenów lokalnych.
Karta statusu
Komponent korzysta z tokenów dla tła, obramowania, promienia i odstępów.
--status-bg#eff6ff--status-border#bfdbfe--status-accent#2563eb
Karta statusu
Wariant nie kopiuje całego CSS. Nadpisuje tylko semantyczne tokeny.
--status-bg#f0fdf4--status-border#86efac--status-accent#16a34a
Najczęstsze błędy początkujących
- Tworzenie tokenów dla każdej pojedynczej wartości bez realnej skali.
- Nazywanie tokenów tylko po kolorze, gdy komponent potrzebuje znaczenia semantycznego.
- Mieszanie tokenów globalnych z lokalnymi bez jasnej konwencji.
- Używanie fallbacków w
var()jako sposobu na omijanie braków w systemie. - Nadpisywanie tokenów w zbyt wielu miejscach naraz.
- Dodawanie tokenów, których nikt nie używa w komponentach.
Mini zadanie
Zbuduj mały zestaw tokenów dla kart informacyjnych.
- Zdefiniuj w
:roottokeny dla koloru akcji, sukcesu, powierzchni i obramowania. - Dodaj skalę odstępów:
--space-sm,--space-md,--space-lg. - Dodaj tokeny promienia i cienia.
- Zbuduj klasę
.info-cardkorzystającą wyłącznie z tokenów. - Dodaj wariant
.info-card--success, który nadpisuje tylko lokalne tokeny wariantu.
Checklista
- Potrafię zdefiniować custom property i użyć jej przez
var(). - Rozumiem różnicę między tokenem bazowym i semantycznym.
- Potrafię zaprojektować małą skalę odstępów, promieni i cieni.
- Wiem, kiedy użyć fallbacku w
var(). - Potrafię nadpisać token lokalnie dla wariantu komponentu.
- Nie dodaję tokenów, które nie mają zastosowania w realnym UI.
Podsumowanie lekcji
Zmienne CSS i design tokens pomagają utrzymać spójność wizualną oraz zmniejszają koszt zmian w projekcie. Najważniejsze jest rozdzielenie surowych wartości od semantycznych decyzji UI i konsekwentne stosowanie tokenów w komponentach.
Kolejny krok roadmapy to kaskada, specyficzność i @layer.