Deklarowanie i używanie zmiennej CSS
Zmienna CSS, oficjalnie custom property, to właściwość, której nazwa zaczyna się od --. Zadeklaruj ją raz, zwykle w :root, żeby dziedziczyła ją cała strona, i odczytuj w dowolnym miejscu przez var().
Zmień --brand na #16a34a, a obramowanie karty i przycisk zmienią się razem. O to właśnie chodzi: jedna wartość, jedno miejsce do jej zmiany. Zmienne łączą się też z calc(), co widać po bocznym paddingu przycisku.
Składnia
:root {
--name: value; /* declare */
}
.element {
color: var(--name); /* use */
color: var(--name, #111827); /* use, with a fallback */
padding: calc(var(--space) * 2); /* compute with it */
}
| Zasada | Szczegóły |
|---|---|
| Nazwa | Zaczyna się od --, potem litery, cyfry, - lub _. Wielkość liter ma znaczenie: --Brand to nie --brand. |
| Wartość | Prawie wszystko: kolor, długość, lista, string. Nie jest sprawdzana, dopóki nie zostanie użyta. |
| Gdzie deklarować | W dowolnej regule. :root dla globalnych, selektor komponentu dla wartości lokalnych. |
| Dziedziczenie | Custom properties są dziedziczone, więc dziecko widzi wartości swoich przodków. |
Gdzie działa var() | Tylko w wartościach właściwości, nie w selektorach, nazwach właściwości ani warunkach @media. |
:root wybiera element <html>. Używa się go zamiast html, bo ma specyficzność klasy, a zwyczajowo oznacza "ustawienia globalne".
Zasięg: nadpisywanie zmiennej w komponencie
Ponieważ zmienne są dziedziczone, ponowne zadeklarowanie zmiennej na elemencie zmienia ją dla tego elementu i wszystkiego, co jest w nim w środku. Reguła, która używa zmiennej, pozostaje taka sama.
Warianty ustawiają tylko zmienną, nigdy samo obramowanie. Dodanie czwartego wariantu to jedna linijka.
Wartości zapasowe
var(--name, fallback) używa wartości zapasowej, gdy zmienna nie jest zdefiniowana na elemencie ani na żadnym przodku. Wszystko po pierwszym przecinku jest wartością zapasową, więc sama może zawierać przecinki (var(--font, Georgia, serif)) i może być kolejnym var().
Zmiana zmiennych w JavaScripcie: przełącznik motywu
JavaScript może ustawić zmienną na dowolnym elemencie przez style.setProperty(). Ustaw ją na document.documentElement (elemencie <html>), a cała strona się dostosuje. Częstszy wzorzec przełącza klasę, która na nowo definiuje zmienne:
Wartość zmiennej odczytasz przez getComputedStyle(element).getPropertyValue('--text'). Pamiętaj, że setProperty zapisuje styl inline na <html>, który wygrywa z klasą .dark, więc po kliknięciu drugiego przycisku kolor tekstu nie zmienia się w żadnym z motywów, dopóki wartość inline nie zostanie usunięta przez root.style.removeProperty('--text').
Przekazywanie wartości z HTML
Zmienna w atrybucie style to najczystszy sposób na przekazanie arkuszowi stylów danych konkretnego elementu. Wygląd zostaje w CSS, a HTML dostarcza tylko liczbę.
calc(var(--value) * 1%) zamienia zwykłą liczbę na procent. Zmienne mogą się też zmieniać wewnątrz media query: @media (min-width: 900px) { :root { --space: 20px; } } sprawia, że każdy odstęp korzystający z --space rośnie na szerokich ekranach.
Pułapka nieprawidłowej wartości
Przeglądarka nie może z góry wiedzieć, czy zmienna ma wartość prawidłową dla właściwości, która jej używa. Jeśli nie ma, właściwość nie wraca do poprzedniej deklaracji w regule. Staje się nieprawidłowa na etapie wartości obliczonej i zachowuje się tak, jakby miała wartość unset: właściwości dziedziczone biorą wartość rodzica, a pozostałe swoją wartość początkową.
Tekst dziedziczy 16px z <body>, a border-width wraca do wartości początkowej medium, którą przeglądarki rysują jako 3px. Bez zmiennych nieprawidłowa deklaracja jest pomijana, a ta przed nią zostaje; ze zmiennymi jest już na to za późno. Wartość zapasowa nie pomoże, gdy zmienna jest zdefiniowana, ale błędna: działa tylko dla niezdefiniowanej zmiennej.
Zmienne CSS vs zmienne Sass
| Zmienne CSS | Zmienne Sass | |
|---|---|---|
| Składnia | --brand: #2563eb; i var(--brand) | $brand: #2563eb; |
| Kiedy są rozwiązywane | W przeglądarce, na żywo | Podczas kompilacji, znikają z wyniku |
| Zmiana na poziomie elementu | Tak, przez dziedziczenie | Nie |
| Zmiana klasą lub media query | Tak | Nie |
| Zmiana z JavaScriptu | Tak | Nie |
| Użycie w selektorach lub warunkach media | Nie | Tak |
Jedne i drugie dobrze współpracują: wiele projektów używa Sass do logiki na etapie kompilacji i generuje zmienne CSS dla wszystkiego, co ma się zmieniać z motywem.
Częste błędy
- Zapomniane dwa myślniki.
var(brand)oraz--brandzadeklarowana jako-brandnie działają. - Użycie zmiennej w media query.
@media (min-width: var(--bp))jest nieprawidłowe. Warunki media wymagają dosłownych wartości. - Oczekiwanie, że wcześniejsza deklaracja przetrwa nieprawidłową zmienną. Nie przetrwa; zobacz pułapkę powyżej.
- Złe łączenie jednostek.
--gap: 10;, a potemmargin: var(--gap)pxnie daje10px. Użyjcalc(var(--gap) * 1px)albo zapisz10px. - Deklaracja na niewłaściwym elemencie. Zmienna zadeklarowana na
.cardnie jest widoczna dla rodzeństwa ani rodzica; wspólne wartości deklaruj w:root.
Najczęściej zadawane pytania
Jak zadeklarować zmienną CSS?
Wpisz w regule właściwość, której nazwa zaczyna się od dwóch myślników, zwykle w :root dla wartości globalnej: :root { --brand: #2563eb; }. Odczytasz ją w dowolnym miejscu przez var(--brand), na przykład color: var(--brand);.
Co to jest :root w CSS?
:root to pseudoklasa, która wybiera element główny dokumentu, czyli <html> na stronie HTML. Zmienne zadeklarowane w niej dziedziczy każdy element. Ma specyficzność klasy, więc wygrywa ze zwykłym selektorem html.
Jak ustawić wartość domyślną zmiennej CSS?
Przekaż drugi argument do var(): color: var(--accent, #2563eb);. Wartość zapasowa jest używana, gdy --accent nie jest zdefiniowana na elemencie ani na jego przodkach. Nie jest używana, gdy zmienna jest zdefiniowana z wartością nieprawidłową dla danej właściwości.
Jak zmienić zmienną CSS w JavaScripcie?
Wywołaj setProperty na stylu elementu: document.documentElement.style.setProperty('--brand', '#16a34a'). Wszystkie reguły używające var(--brand) aktualizują się od razu. Bieżącą wartość odczytasz przez getComputedStyle(el).getPropertyValue('--brand').
Czym różnią się zmienne CSS od zmiennych Sass?
Zmienne Sass są zastępowane wartościami podczas kompilacji arkusza stylów, więc nie mogą się zmieniać w przeglądarce. Zmienne CSS żyją w przeglądarce: są dziedziczone, mogą mieć inną wartość na każdym elemencie, reagują na media queries i klasy, i można je zmieniać z JavaScriptu.
Czy w nazwach zmiennych CSS ma znaczenie wielkość liter?
Tak. --Brand i --brand to dwie różne zmienne, w przeciwieństwie do zwykłych nazw właściwości, takich jak color, w których wielkość liter nie ma znaczenia.