Menu

Zmienne CSS: custom properties, :root i var()

Zmienne CSS (custom properties) przechowują wartość w jednym miejscu i pozwalają używać jej ponownie przez var(). Dowiedz się, jak deklarować je w :root, ograniczać ich zasięg i nadpisywać, ustawiać wartości zapasowe, przełączać motywy w JavaScripcie i unikać pułapki nieprawidłowej wartości.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

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 */
}
ZasadaSzczegóły
NazwaZaczyna 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.
DziedziczenieCustom 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 CSSZmienne Sass
Składnia--brand: #2563eb; i var(--brand)$brand: #2563eb;
Kiedy są rozwiązywaneW przeglądarce, na żywoPodczas kompilacji, znikają z wyniku
Zmiana na poziomie elementuTak, przez dziedziczenieNie
Zmiana klasą lub media queryTakNie
Zmiana z JavaScriptuTakNie
Użycie w selektorach lub warunkach mediaNieTak

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 --brand zadeklarowana jako -brand nie 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 potem margin: var(--gap)px nie daje 10px. Użyj calc(var(--gap) * 1px) albo zapisz 10px.
  • Deklaracja na niewłaściwym elemencie. Zmienna zadeklarowana na .card nie 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.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ