Pravděpodobně jste se někdy setkali s CSS preprocesory, které umožňují definovat různé proměnné a ty pak využívat dále v kódu. Například si ke slovu modra přiřadíte kód barvy #0066CC a ve zbytku CSS už jen zadáváte slovo modra. Pokud budete chtít odstín změnit, stačí to provést jen u definice na začátku.
Nemusíte se samozřejmě omezovat jenom na barvy. Syntaxe se v různých preprocesorech liší. Ať už sáhnete pro SASS nebo mém oblíbeném LESS, budete mít tyto i další vychytávky k dispozici. Preprocesor pak z takto připraveného zápisu vyplivne klasické CSS.
Ale právě nutnost zpracovat zápis pomocí nějakého dalšího nástroje je něco, co řadu lidí od preprocesorů odrazuje. Nebylo by šikovnější, kdyby webové prohlížeče samy od sebe rozuměly zápisu proměnných přímo v klasickém CSS? Samozřejmě bylo. A ještě lepší je, že to tak funguje.
Podpora proměnných v CSS je plně funkční v aktuálních verzích prohlížečů Edge, Firefox, Chrome a Safari. V případě mobilních i v iOS Safari a Chrome pro Android. Na problém tak narazíte v IE11, mobilní Opeře a starém klasickém prohlížeči v Androidu. Je otázka, zda je nutné to řešit.
V případě Maxiorla činí uživatelé s Internet Explorerem 4,66 % celkové návštěvnosti. Úplně zanedbatelné to není.
Není to jen o proměnných
V anglickém pojmenování se používá výraz CSS custom properties. To je trochu širší pojem, než CSS variables a nejsem si jist, jak jej správně přeložit do češtiny. Budu se tedy držet anglického názvosloví. Jde každopádně o to, že tuto novou vychytávku v CSS není nutné používat jen a pouze k definici proměnných, jako jsou barvy, velikosti nebo názvy fontů.
Zatímco v CSS preprocesorech jste si definovali nějakou proměnnou a poté ji preprocesor nahradil příslušnou hodnotou, když tvořil CSS, tak v případě custom properties můžete k těmto uživatelským hodnotám přistupovat i pomocí JavaScriptu. A to velice elegantně, což otevírá velký prostor pro zpříjemnění uživatelského prožitku z práce s webem.
Začínáme s CSS custom properties (variables)
Dvě věci na začátek. Proměnná je v CSS deklarovaná uvnitř zapsaného elementu a dostupná v rámci jeho potomků. Pokud ji chcete používat v rámci všech prvků na stránce, definujte ji v prvku :root{…}. Pokud proměnnou zadáte v .prvek{…}, pak bude dostupná i v .prvek .potomek {…}, ale nikoli v .jiny-prvek {…}.
Proměnné či uživatelské vlastnosti CSS se zapisují se dvěma pomlčkami na začátku. Zbytek může být rozdělen pomlčkami i podtržítky. Nezapomeňte, že CSS variables jsou citlivé na velikost znaků. Následující čtveřice je vždy jiná definice: --moje_barva, --moje-barva, --mojeBarva, --mojebarva.
A teď už ke konkrétnímu příkladu:
:root{ --hlavni-barva: #0066CC; --barva-textu: #222; } a{ color: var(--hlavni-barva); text-decoration: underline; } p{ color: var(--barva-textu); } h1{ color: var(--hlavni-barva); }
Jak vidíte, definice je uvedena pro prvek :root, použití proměnné pak znamená dát ji do funkce var(). Vnímáte ten rozdíl oproti klasickému CSS zápisu, kde byste v tomto případě museli dvakrát opakovat zápis kódu hlavní barvy? A také jej dvakrát měnit, kdybyste chtěli použít jiný odstín? S použitím CSS variables to stačí změnit jen v definičním prvku :root.
Výchozí hodnoty CSS custom properties
Teď už se dostáváme z oblasti kódování do oblasti, kterou bych se nebál nazvat programováním. Představte si, že z nějakého důvodu prohlížeč nenalezne definici pro proměnnou --barva-textu. On samozřejmě nezkolabuje. V případě odkazu by tam prostě použil výchozí barvu ze svého nastavení.
Ovšem při práci s custom properties můžete v CSS říci, jaký bude fallback. Výchozí hodnota, která se použije v případě, že daná proměnná není z nějakého důvodu nastavena.
h1{ color: var(--hlavni-barva, blue); }
Pokud by prohlížeč nenalezl definici pro --hlavni-barva, pak by použil základní modrou.
Čtení a nastavování CSS custom properties pomocí JavaScriptu
Zatím jsme si s použitím proměnných v CSS ušetřili práci. S JavaScriptem tomu dodáme trochu šťávy. Pro zjištění hodnoty vlastní proměnné máme k dispozici dvě možnosti:
// získání hodnoty z inline stylu element.style.getPropertyValue("--hlavni-barva"); // získání hodnoty definované kdekoli v CSS getComputedStyle(element).getPropertyValue("--hlavni-barva");
Nastavení hodnoty vlastní proměnné v CSS pomocí JavaScriptu pak vypadá následovně:
element.style.setProperty("--hlavni-barva", "#0066cc");
Podívejme se nyní na jednoduchý příklad, který nabídne na stránce dvojici tlačítek pro přepínání barevného schématu webu s využitím CSS variables:
V HTML výstupu máme nadpis a odstavec textu s odkazem. CSS definice stanovuje hlavní barvu modrou a obarvuje jí nadpis i odkaz. V JavaScriptu mám dvě obsluhy událostí po kliknutí na tlačítko, jedna nastaví do značky body proměnnou --hlavni-barva na modrou, druhá na kód zelené barvy. Nadpis a odkaz proměnné ze značky body dědí a tím pádem se po kliknutí na tlačítka mění barevné schéma stránky.
Co s nepodporovanými prohlížeči?
Použití CSS custom properties (variables) je tedy velice zajímavé nejenom z úspory času a přehlednosti kódu, ale také díky možnosti s hodnotami pracovat pomocí JavaScriptu. U webových prohlížečů, které tuto část CSS nepodporují máte několik možností řešení.
První z nich je prostě definice klasického CSS zápisu, kdy prohlížeč nepodporující CSS proměnné prostě bude jejich zápis ignorovat:
a{ color: "0066cc"; color: var(--hlavni-barva); }
Bohužel pak celý koncept postrádá efekt zjednodušení zápisu. Můžete ale využít pluginu pro PostCSS, který definice proměnných převede na tento klasický zápis pro staré prohlížeče automaticky.
Nebo prostě uživatelům se zastaralým prohlížečem nabídnete barevně trochu odlišný web. Například jen dvoubarevný, přičemž si myslím, že zápis dvou barev jako výchozí definice bez proměnných není až tak velký problém. Hezky to popisuje Andy Clarke v článku Getting Hardboiled with CSS Custom Properties.
Třetí možností je použití nějakého polyfillu, který podporu CSS variables minimálně do IE11 přidá. Jeden takový pokus najdete na CodePenu.
Tvůrce webů z Brna se specializací na Drupal, WordPress a Symfony. Acquia Certified Developer & Site Builder. Autor několika knih o Drupalu.
Web Development Director v Lesensky.cz. Ve volných chvílích podnikám výlety na souši i po vodě. Více se dozvíte na polzer.cz a mém LinkedIn profilu.
Podobné články
Komentáře k článku
Nikoliv. Je to značné zjednodušení práce a v kombinaci třeba s tím pluginem pro PostCSS to pak šlape všude. A že to nefunguje v IE11, který je defakto odepsaný, to je sice mrzuté, ale čas to dříve či později vyřeší.
Podle webu caniuse.com má živoucí relikvie IE 11 ve světě 2,84% podíl na trhu prohlížečů, v Česku smutných 4,24%, ale i tak se dá ignorovat. Problém mohly být starší Edge, které CSS Variables také pořádně neumí a někdy se je uživateli nedaří aktualizovat (závislé na Windows update), ale i to se relativně nízkou používaností Edge vyřešilo tak nějak samo.
Dosavadní řešení mohlo být buď časté opakování jedné barvy v kódu, nebo mezistupeň s kompilací, třeba LESS. S CSS variables se dá vrátit k čistému CSS.
Variables jsou fajn, ale těžko zastanou mixiny, extend, funkce, nestování a další jako u SASSu např...
CSS používám, ale má to jednu vadu. Na ladění jsem používal Firefox + WebDeveloper. Jenže Firefox od verze 57 změnil API a webDeveloper tím šel vítekam. Přišel totiž o dost zásadní funkci CSS inspekt, takže kvůli tomu musím zůstávat u verze 56.0.2 a příslušného Webdeveloperu 1.2. :(
Procházení a změny CSS má ale i zabudovaný nástroj pro vývojáře ve Firefoxu, viz https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Exa... Nebo měl WebDeveloper plugin něco lepšího?
Hm. Jestli tomu dobře rozumím, tak nahradím v css něco co funguje něčím, co funguje jen někde. A pak složitě řešit, aby to nefungovalo jen někde a všude? Mi z té rovnice vychází zůstat u dosavadního řešení, že novinka je takový zbytečný kočkopes…