W tym wpisie poznasz potężną funkcję nowoczesnych przeglądarek, czyli Zmienne CSS (ang. css variables, custom properties). Dowiesz się, dlaczego zmienne CSS od lat były jedną z najbardziej pożądanych funkcji w CSSie i jak zacząć z nich korzystać, aby
pisać lepszy CSS.
Wstęp
W ostatnich latach dużą popularnością cieszyły się (i przez cały czas są często stosowane) preprocesory CSS takie jak SASS/LESS, dzięki którym możemy wykrzesać z CSSa o wiele więcej. Technologie te często nazywane są CSSem ma sterydach, bo dają deweloperom dodatkowe korzyści:
- umożliwiają zagnieżdżanie selektorów CSS
- pozwalają na import innych plików
- pozwalają deklarować zmienne
Ostatnio jedną z tych korzyści możemy uzyskać dzięki natywnego CSSa (bez preprocesora). Mam tutaj na myśli właśnie CSS variables, Custom Properties czy po polsku zmienne CSS 🥳 .
Co to są zmienne CSS/CSS variables?
Zmienne CSS pomagają uniknąć powtórzeń, ułatwiają ponowne wykorzystanie stylów oraz wyeliminowanie niespójności. Wszystko, co musisz zrobić, to zadeklarować je raz i wywołać w miejscu, w którym chcesz ich użyć. Ponadto zmienne CSS mają dodatkową przewagę nad zmiennymi, które możesz zadeklarować dzięki preprocesorów. Jest to fakt, iż masz do nich dostęp i możesz nimi manipulować przez JavaScript.
Wyobraź sobie, iż tworzysz stronę internetową, która wszędzie będzie korzystała z głównego koloru. Przyciski, nagłówki i linki będą miały taki sam kolor. Załóżmy, iż będzie to kolor czerwony. Kończysz stylowanie i zadowolona pokazujesz efekty swojej pracy klientowi. I tutaj zaczynają się schody, bo klient stwierdza, iż wolałby jednak, żeby ten kolor był niebieski… 🤯
Nie jest to coś, co zdarzy się zawsze, ale szanse są większe, niż byś myślała. 😀
I co teraz? Jak z tego wybrnąć?
Opcja 1. Musisz wrócić do wszystkich miejsc, w których użyłaś czerwonego, a następnie zamienić go na niebieski. Brzmi jak łatwizna, prawda? Niby tak, ale co w sytuacji, kiedy liczba tych miejsc wynosi 20, 100 lub choćby więcej i to w różnych plikach?
Opcja 2. Teraz wyobraź sobie, iż użyłaś zmiennej CSS do zadeklarowania wartości koloru i wywołałaś tę zmienną w konkretnych elementach. Następnie, gdy klient zdecyduje się na zmianę koloru, wystarczy zmienić jego wartość w jednym miejscu i ot, tak wszystkie czerwone elementy nagle stają się niebieskie. To jest właśnie potęga zmiennych.
Jeśli czujesz, iż opcja nr 2 jest dla Ciebie, to zapraszam dalej 😀
Składnia, czyli deklarowanie zmiennej CSS
Deklarujesz zmienną w taki sam sposób, w jaki ustawiasz dowolną adekwatność CSS. Jedyną różnicą jest to, iż zmienna musi zaczynać się od dwóch myślników:
--primary-color: #ff0000;
Jak widzisz, nic strasznego. 😊
CSS variables są wrażliwe na wielkość liter
Pamiętaj tylko, iż wielkość liter w nazwach zmiennych ma znacznie: --primary-color to nie to samo co --Primary-color, czy --primary-Color. Przeglądarka odczyta je jako zupełnie niezwiązane ze sobą wartości.
Zakres zmiennej CSS
Istnieją dwa typy zmiennych w zależności od tego, gdzie je zadeklarujesz. Są to zmienne globalne i lokalne.
Zakres globalny 🌎
Jeśli chcesz, aby zmienna była dostępna globalnie, zdefiniuj ją w pseudo selektorze :root. Zmienna będzie wtedy dostępna dla głównego elementu w drzewie dokumentu, zwykle jest to tag <html>. Dziedziczenie zmiennych sprawi, iż zmienna będzie dostępna w obrębie całej strony/aplikacji, ponieważ wszystkie elementy DOM są potomkami tagu <html>.
:root {
--primary-color: #ff0000;
}
Zakres lokalny 🏠
Zmienne globalne mogą być używane przez każdy element w dokumencie, ale możesz chcieć graniczyć ich dostępność do konkretnego selektora. Tutaj z pomocą przychodzą zmienne lokalne, które mogą być używane tylko przez elementy wewnątrz selektora, w którym są zadeklarowane. Przykładowo, jeżeli chcesz, żeby Twoje linki miały inny główny kolor, możesz to zrobić w następujący sposób:
a {
--primary-color: #ff0000;
}
Kiedy zakres globalny, a kiedy lokalny?
W większości artykułów i poradników dotyczących CSS variables spotkasz się głównie z zasięgiem globalnym. Co jest spoko, jeżeli nadajesz, jak sama nazwa podpowiada zmienne używane globalnie, czyli na całej stronie/aplikacji. Mogą to być elementy takie jak główny kolor, czcionka itd. Wartości dotyczące poszczególnych elementów warto odseparować jako zmienne lokalne.
Dla przykładu --link-hover-bg-color wygląda na wartość, która dotyczy linków, więc moim zdaniem więcej sensu miałoby dodanie jej bezpośrednio do powiązanego selektora. Możemy wtedy dodatkowo uprościć jej nazwę do --hover-bg-color, bo z góry wiemy, iż chodzi o link. Prosty zabieg, który sprawia, iż od razu łatwiej znaleźć taką zmienną w pliku CSS 😉
Ogólna zasada jest taka: używaj zmiennych lokalnych, dopóki nie będziesz potrzebować zmiennej globalnej. jeżeli dojdziesz do takiego momentu, idź dalej w górę. Zmniejszasz w ten sposób listę zmiennych globalnych, których z rozwojem aplikacji jest naprawdę sporo. Dzięki temu sprawiasz, iż Twój kod staje się bardziej przejrzysty, znacznie czystszy i przewidywalny.
Jak skorzystać z zadeklarowanej zmiennej CSS?
Aby skorzystać z wcześniej zadeklarowanej zmiennej i sprawić, aby buttony, linki i nagłówki z wcześniejszego przykładu dostały odpowiedni kolor, musisz użyć funkcji var() i przekazać nazwę zmiennej dla głównego koloru jako parametr:
Incepcja zmienych CSS
Możesz odwoływać się do zmiennych przy deklarowaniu nowych zmiennych. Brzmi tajemniczo, ale myślę, iż przykład najlepiej to wyjaśni.
Jak widzisz, deklarując zmienną, posłużyłam się inną zmienną do nadania jej wartości. Super, prawda? Można w ten sposób bardzo łatwo robić różne wariacje dla styli elementów takich jak np. tło buttona po najechaniu albo dla stanu disabled.
See the Pen
CSS variables – nested variables by frontowisko (@frontowisko)
on CodePen.
W razie W, czyli wartość zapasowa dla zmiennej CSS
Jeśli przeglądarka uzna, iż wartość, którą nadałaś swojej zmiennej, jest nieprawidłowa, sprawdzi, czy nie istnieje wartość domyślna, zapasowa. Taka sytuacja może mieć miejsce, kiedy np.:
- zrobisz literówkę w nazwie zmiennej, do której się odnosisz
- zmienna jest poza zakresem
- wartość zmiennej będzie mieć nieodpowiedni typ dla danej adekwatności css
Zmienne CSS i dziedziczenie
Zmienne CSS elementu mogą być dziedziczone przez jego dzieci, jeżeli dzieci nie mają własnych styli lub nadpisanej wartości dla konkretnej zmiennej CSS.
Z powyższego przykładu element class=”rodzic” nadpisuje rozmiar czcionki dziedziczony z :root. Jego font-size ostatecznie przyjmie wartość 22px. Taki sam rozmiar odziedziczą jego dzieci.
Element class=”drugie-dziecko” otrzymuje czcionkę o rozmiarze 22px, którą odziedziczył po swoim elemencie nadrzędnym (klasa=”rodzic”).
Ale element class=”pierwsze-dziecko” z drugiej strony otrzymuje rozmiar czcionki 16pxm, ponieważ wartość zadeklarowanej zmiennej została teraz nadpisana.
Zmienne CSS i specyficzność
Specyficzność działa ze zmiennymi CSS tak samo, jakbyś pisała zwykły kod CSS. Załóżmy na przykład, iż deklarujesz zmienną koloru dwa razy w tym samym selektorze, najpierw jako czerwony, a następnie jako zielony, a następnie wywołujesz zmienną w swoim elemencie p. Jak myślisz, jaki kolor miałby element p?
Jeśli odpowiedziałaś, iż zielony, to masz rację. Przeglądarka podczas przeglądania kodu najpierw zapisuje zmienną jako czerwoną, a gdy zobaczy, iż zmienna jest ponownie zadeklarowana z inną wartością, zapisuje ją na zieloną.
Możemy pójść dalej i nadpisać tę zmienną w samym selektorze p:
I tak masz rację, teraz nasz tekst będzie miał kolor różowy. Tym razem również obyło się bez niespodzianek. 🙂
Media Queries ze zmiennymi CSS
Korzystanie ze zmiennych CSS w ramach media queries odbywa się tak samo jak w poprzednich przykładach. Deklarujesz i korzystasz z nich w taki sam sposób.
Jedna mała WADA 😥
Nie wiem dokładnie, czy to wada, ale na pewno jest to ograniczenie. Niestety nie możemy używać zmiennych CSS w deklaracji media queries. Oznacza to, iż coś takiego nie zadziała:
Możemy to obejść na 2 sposoby:
- skorzystać z preprocesora SASS/LESS
- skorzystać z pluginu do PostCSSa.
Ewentualnie możesz poczekać na rozwój propozycji dodania zmiennych środowiskowych do CSS, które wydają się rozwiązywać ten problem albo przymknąć na to oko i nie stosować na razie zmiennych w deklaracjach.
Funkcja calc() i zmienne CSS 🧮
Aby wykonać operacje matematyczne na zmiennych CSS, musisz użyć funkcji calc(). jeżeli znasz już tę funkcję, to mój przykład nie będzie dla Ciebie zbyt dużym zaskoczeniem:
Wygląda analogicznie do nadawania wartości dla zwykłej adekwatności w CSS.
Manipulowanie zmiennymi CSS przy pomocy JavaScriptu 🔥
Jedną z największych zalet zmiennych CSS jest to, iż możesz uzyskać do nich dostęp i modyfikować ich wartość dzięki JavaScript. Możesz także zadeklarować nowe zmienne.
Zmiana wartości zmiennej:
const element = document.getElementById('my-element');
element.style.setProperty('--variable-name', 'a-value');
Pobieranie wartości zmiennej:
Dla elementu :root
const styles = getComputedStyle(document.documentElement)
const value = String(styles.getPropertyValue('--variable-name')).trim()
Dla konkretnego selektora
const element = document.getElementById('my-element');
const styles = getComputedStyle(element);
const value = String(styles.getPropertyValue('--variable-name')).trim();
Trochę szaleństwa ze zmiennymi CSS i JSem
Zmienne CSS są dynamiczne (a nie statyczne jak w przypadku preprocesorów), więc mamy kolejną interesującą możliwość. Możemy np. zmienić pozycję określonego elementu na ekranie, zgodnie z pozycją kursora zmieniając wartości zmiennych CSS.
Fajnie, co? 🤩
CSS Variables i obsługa przeglądarek
Podsumowanie
Zmienne CSS pozwalają efektywniej tworzyć UI. Korzystanie ze zmiennych CSS skutkuje mniejszą liczbą powtórzeń, lepszą czytelnością i większą elastycznością. Możemy łatwiej zarządzać kolorami, czcionkami czy wartościami animacji na stronie. Piszemy jednocześnie
znacznie mniej kodu i mamy znacznie większą skalowalność w obrębie całej strony/aplikacji. Dodatkową zaletą CSS Variables jest fakt, iż możemy z nich korzystać bez względu na dotychczasowy stack technologiczny (sass, less, bulma czy styled-components z React.js), bo są częścią z natywnego CSSa.
A Ty? Korzystałaś już z CSS variables? Daj znać w komentarzu! 🙂