Zmienne w CSS

Zmienne w kaskadowych arkuszach stylów to bardzo przydatne narzędzie w pracy nad projektem, jak również integracji stylów z JavaScriptem. Przyjrzyjmy się im bliżej.

Zmienne we frontendzie to nie tylko domena JavaScriptu. Posługuje się nimi również język CSS. Stanowią one masę przydatnych dla programisty rozwiązań i ułatwień, które może stosować dla zwiększenia komfortu pisania stylów oraz zarządzania nimi z poziomu JSa.

Dlaczego zmienne w CSS to dobra rzecz?

Część z was - czytelników - korzystała pewnie z Sass - preprocesora do CSSa. Sass korzysta ze zmiennych, co ma w głównej mierze ułatwić i przyspieszyć pracę nad stylami. Szczerze powiedziawszy, niezbyt często z niego korzystam. Nie wszyscy jednak wiedzą, że CSS również posiada zmienne.  Do stylowania przeważnie używam Styled Components, a do przechowania globalnych zmiennych używam modułu Styled Components Theme Provider. A kiedy nie używam Reacta, to zamiast używania zmiennych "sassowych", wybieram właśnie czyste zmienne CSSowe. Mają podobne zastosowanie i cel, czyli ułatwienie życia programiście piszącemu tysięczną linijkę kodu.

Jak to działa?

Przypuśćmy, że tworzymy projekt, który w swojej kolorystyce posiada dwa przewodnie kolory - niech to, dla przykładu, bedzie kolor aliceblue oraz rgb(123, 231, 8). Skoro są to kolory przewodnie na stronie, jasnym jest, że będziemy ich używać często i gęsto dla wielu elementów DOMu czy komponentów. Zamiast przepisywania w kółko tego samego koloru, którego za szybko nie zapamiętamy, użyjmy zmiennych w CSS. Zrobimy to w ten sposób:

:root {
    --primaryColor: aliceblue;
    --secondaryColor: rgb(123, 231, 8);
}

Pseudoselektor :root odnosi się - jak sama nazwa wskazuje - do korzenia (węzła) dokumentu. Można powiedzieć, że jest on najpoteżniejszym selectorem CSSa w dokumencie. W nim ustalimy zmienne globalne - widoczne dla wszystkich innych selektorów. Kiedy więc się rozmyślimy i zechemy zmienić dany kolor, to wystarczy, że edytujemy jedną zmienną, a nie wszystkie właściwości dla selektorów.  Zmienne w css deklarujemy za pomocą przedrostka --. Jest to jeden z dwóch sposobów na zrobienie tego w dokumencie. Zmienne, podobnie jak właściwości dziedziczone są w dół. Możemy je deklarować tak naprawdę na każdym poziomie tworzenia stylów. Bardzo przydatną rzeczą jest możliwość nadpisania zmiennych w dowolnym selektorze niższym, kiedy jest taka potrzeba.

Korzystanie ze zmiennych

Przypuśćmy, że mamy dwa elementy menu (ul) - jeden w drugim. Chcemy przypisać color ze zmiennej do zewnętrznego menu. HTML będzie wyglądać tak:

{
    <ul class="list-1">
      <li>element 1</li>
      <li>element 2</li>
      <ul class="list-2">
        <li>element 3</li>
        <li>element 4</li>
        <li>element 5</li>
      </ul>
      <li>element 6</li>
    </ul>
}

A tutaj CSS z wykorzystaniem wcześniej zdefiniowanych w :root zmiennych:

{
    :root {
        --primaryColor: aliceblue;
        --secondaryColor: #7be708;
      }

      .list-1 {
        color: var(--primaryColor);
      }
}

Używanie zmiennych odbywa się za pomocą funkcji var([nazwa-zmiennej]). Tak jak wspomniałem wcześniej, możemy nadpisać zmienną w niższym selektorze. I tak, chcąc zmienić kolor, np. na czerwony, dla drugiego menu zastosujemy zapis:

{
    :root {
        --primaryColor: aliceblue;
        --secondaryColor: #7be708;
      }

      .list-1 {
        color: var(--primaryColor);
      }

      .list-2 {
        --primaryColor: red;
        color: var(--primaryColor);
      }
}
zdjęcie tematyczne
Otrzymamy taki rezultat

Integracja JavaScript - zmienne CSS

Wspomniałem wcześniej, że deklarownie zmiennych w samych stylach to nie jedyny sposób na wykonanie tej czynności. Drugim jest oczywiście skorzystanie z ulubionego języka. Aby ustawić zmienną dla selektora :root wykorzystamy dostępną dla stylów w JS właściwość setProperty(). Zrobimy to tak:

document.documentElement.style.setProperty(`--primaryColor`, 'red');

Nic trudnego, prawda? Daje nam to olbrzymie możliwości dynamicznego przypisywania zmiennych do stylów, a co za tym idzie możliwość personalizacji layoutu globalnie dla każdego użytkownika naszej aplikacji (jest to tylko przykład zastosowania) i masę innych rzeczy. Oczywiście można przypisywać wartości właściwości dla każdego elementu w DOMie, ale po co, jeśli można robić to mądrzej? Zmienne w CSS często też potrafią zastąpić takie rozwiązania jak CSS-in-JS (mam tu na myśli Styled Components) i równie często warto używać je w projektach reactowych. Dodam jeszcze, że użycie setProperty() w razie kiedy dana zmienna nie istnieje, to JavaScript ją stworzy. Jeżeli natomiast istnieje - odpowiednio nadpisze.

Im dalej w las, tym więcej wszystkiego

Korzystając tutaj z chwili na podsumowanie, chciałbym poruszyć jeden problem. Problem dotyczący mnogości dostępnych rozwiązań technologicznych. Na same zmienne w stylach mamy masę sposobów: Styled Components i jego ThemeProvider, preprocessory LESS i SaSS, zmienne w CSSie i pewnie jeszcze wiele więcej, o których nawet nie mam pojęcia. To samo tyczy się wszystkiego innego co dotyczy programowania. Jest pełno rozwiązań, a każde z nich ma swoje wady i zalety. Nie ma jedynego słusznego podejścia do dziedziny jakim jest programowanie. Poznawajmy ten świat przez pryzmat ciężkiej pracy i fascynujmy się nim, ale nie ufajmy ślepo tylko jednemu rozwiązaniu, które w niektórych aspektach jest pewnie znacznie gorsze od innego. Bądźmy elastyczni, bądźmy pokorni i bądźmy mądrzy w tym co robimy. Mieszajmy, eksperymentujmy i bawmy się kodem, z którego możemy wyrzeźbić dosłownie wszystko. Czasem to, że mamy tak ogromny wybór technologii dostępnych na rynku może przytłoczyć. Nie śpieszmy się więc także zanadto, by poznać to wszystko. Bo życia nam nie starczy.

© Damian Kalka 2021
Wszelkie prawa zastrzeżone