Vrstvy v CSS
S rostoucí složitostí projektů a webových aplikací roste i složitost jejich CSS kódu. Často se používají různé knihovny či frameworky nebo se udržují historické kusy a skloubit cizí CSS kód s vlastním bývá bolestivé. Koncept vrstev v CSS míří právě na tyto situace. Dává vám do ruky silné a zároveň jednoduché nástroje, jak rozhodovat mezi potenciálně konfliktními pravidly.
Když jsem popisoval priority v CSS, uvedl jsem, že nejprve se rozhoduje podle původu a důležitosti pravidel. Na tom vrstvy nic nemění. Následuje posuzování podle konkrétnosti a případně podle pořadí a tady už se mohou uplatnit. Pravidla stejného původu (typicky to budou obyčejná pravidla zadaná autorem stránky) lze seskupit do vrstev a celý mechanismus kaskádování, tedy rozhodování o tom, které pravidlo se použije, probíhá v každé vrstvě samostatně a nezávisle na ostatních. Hodnotu vlastnosti určí poslední vrstva, která jí nějakou hodnotu přiřadila.
Definice vrstvy
Vrstvu vytvoříte velmi jednoduše konstrukcí:
@layer
název{
pravidla
}
Výsledkem bude, že pravidla se vloží do vrstvy s daným
názvem. Vrstvu nemusíte vytvořit celou najednou. V CSS se může
vyskytnout několik konstrukcí @layer
se stejným názvem a
všechna jejich pravidla budou zařazena do jedné společné vrstvy. Pokud se máte
alespoň trochu rádi, nedělejte to a definujte vždy celou vrstvu naráz. Vyznávat
se v kódu, kdy jsou části vrstvy rozptýleny na několika různých místech, není
nic příjemného.
Druhou možností, jak vytvořit vrstvu, je použít @import
s
klíčovým slovem layer
:
@import url('mujfw.css') layer framework;
Tento příkaz načte CSS kód ze souboru mujfw.css a vloží jej do
vrstvy nazvané framework. Pokud byste k němu chtěli něco přidat, může
následovat @layer framework {...}
, v němž přidáte do vrstvy další
pravidla, zařazená za ty ze souboru:
/* vytvoří vrstvu framework */ @import url('mujfw.css') layer framework; /* následující se do ní přidá */ layer framework { .cosi { color: blue; } }
Pořadí vrstev
Vrstvy se uplatňují v tom pořadí, ve kterém jsou vytvořeny. Stejně jako u běžných pravidel výsledek pozdější vrstvy přepíše výsledky svých předchůdkyň. Například při deklaraci:
@layer raz { a { color: red; } } @layer dva { a { color: blue; } }
budou odkazy modré. Vrstva raz
jim nastaví červenou barvu,
vrstva dva
barvu modrou a jelikož je pozdější, uplatní se její
výsledek.
Vrstvy ale můžete vytvořit i tak, že na začátku CSS kódu použijete
@layer
následovaný čárkami oddělovaným seznamem názvů vrstev.
Vytvoří prázdné vrstvy a bude je uplatňovat ve vámi zvoleném pořadí. Následně
je můžete naplnit pravidly výše popsaným způsobem. Na pořadí to nic nezmění,
vrstvy už jsou vytvořeny, jen se doplňuje jejich obsah. Kdybych na začátek
předchozího kódu doplnil:
@layer dva, raz;
změní se barva odkazů na červenou, protože teď se nejprve uplatní vrstva
dva
a vrstva raz
po ní a přepíše hodnoty po svém.
Tohle umožňuje velmi elegantně kombinovat pravidla z různých zdrojů – některá budou pocházet z frameworku či nějakých knihoven, další budou vaše výchozí a další vrstva bude obsahovat specifické definice, které přizpůsobí a přepíší hodnoty pro určitou konkrétní situaci. Pořadí:
@layer framework, default, specificke;
pak zajistí, že výchozí pravidla případně přepíší ta z frameworku a specifická budou mít přednost i před nimi.
Pokud v CSS použijete vrstvy, doporučuji vždy na začátek vložit
@layer
s jejich pořadím. Jednak tím dáváte najevo, že používáte
vrstvy, jednak jasně uvedete jejich priority, aniž by čtenář musel procházet
kód a hledat, v jakém pořadí jsou vytvořeny.
A co se stane s pravidly, která v žádné vrstvě nejsou? Ta mají přednost před všemi vrstvami. Můžete si to představovat tak, že pravidla mimo vrstvy budou vložena do fiktivní vrstvy, která je vytvořena jako úplně poslední. V následujícím kódu proto budou odkazy červené:
a { color: red; } @layer dva { a { color: blue; } }
Použití
Řekněme, že navazujete na existující CSS, ve kterém jsou odkazy červené, ale vy byste je chtěli mít modré. Bez vrstev byste mohli udělat něco takového:
@import url('stare.css'); a { color: blue; }
Vaše pravidlo až za vloženými, takže přepíše deklaraci barvy prvku
<a>
ze souboru stare.css. Jenže co když v něm je
také pravidlo pro a:hover
, a:visited
,
.hlavnimenu a
a další? Všechny tyhle selektory jsou konkrétnější
než vaše a
, takže dostanou přednost a vaše přidané pravidlo na
jimi nastavené barvě odkazu nic nezmění.
Po staru musíte hledat v existujícím kódu všechna místa, kde se nastavuje, příslušná vlastnost a přidávat odpovídající pravidla, která přepíší hodnotu na takovou, jakou chcete. To je otravné a náchylné k chybám. S vrstvami situaci vyřešíte jednoduše. Existující kód vložíte do jedné vrstvy, vlastní kód do druhé a nastavíte, že má mít přednost:
@layer stare, nove; @import url('stare.css') layer stare; @layer nove { a { color: blue; } }
Mezi vrstvami spolu pravidla nesoutěží. Je jedno, jak konkrétní byl selektor
pravidla, které nastavilo barvu odkazu ve vrstvě stare
. Vrstva
nove
mu přiřazuje modrou barvu a je pozdější, takže odkaz bude
modrý za jakýchkoli okolností.
Může vás to ale také kousnout do nohy. Řekněme, že původní kód invertuje
barvy odkazu po najetí myší. Obsahuje pravidlo pro a:hover
, které
nastaví bílý text na červeném pozadí. Vy jste novou vrstvou přebili barvu odkazu
na modrou, ale barvu pozadí neměníte. Takže po najetí myší bude odkaz modrý na
červeném pozadí, což není ke koukání.
Nedá se proto říci, že při použití vrstev vás vůbec nemusí zajímat, co a za jakých okolností nastavuje kód v jiných vrstvách. Nicméně koexistence s ním bude rozhodně podstatně jednodušší.
zpět: vytváření WWW stránek