Cascada și moștenire
La un moment dat, vă veți afla în situația în care mai multe reguli CSS vor avea selectori care vor ținti același element. În asemenea cazuri, apare o dilemă, și anume: care regulă CSS „câștigă” și sfârșește ca fiind cea care va fi aplicată, în cele din urmă, elementului.
Acest lucru este controlat de un mecanism numit „Cascade”, dar are legătură și cu moștenirea — „Inheritance” — elementele vor moșteni reguli și de la părinți, dar nu și de la alte elemente.
În acest capitol vom lămuri ce este cascada CSS, specificitatea și importanța, și cum proprietățile CSS moștenesc diferite valori.
Stilul final pentru un element poate fi specificat în multe locuri diferite, care pot interacționa în moduri complexe. Această interacțiune complexă face ca CSS să fie foarte puternic, dar, uneori, să creeze confuzie și să fie greu de depanat.
Voi încerca să clarific o parte din această complexitate, iar dacă nu înțelegeți imediat, este normal, pentru că încerc să vă ajut să înțelegeți una dintre cele mai dificile părți din teoria CSS.
Cascada
CSS este abrevierea pentru „Cascading Style Sheets” (Foi de stil în cascadă). Asta înseamnă că, la nivelul cel mai de bază, ordinea regulilor CSS contează — doar că lucrurile sunt mult mai complexe de atât.
Asupra unui element se pot aplica mai multe seturi de reguli definite în CSS. Pentru a decide ordinea în care trebuie aplicate stilurile, standardul definește cascada. Procesul de selecție a regulilor este următorul:
- Se găsesc toate declarațiile care se aplică unui anumit element;
- Se sortează în funcție de origine și nivel de importanță;
- Declarațiile cu același nivel de importanță și cu aceeași origine (sursă) se ordonează după specificitate;
- Dacă au aceeași origine, importanță și specificitate, se aplică în ordinea în care au fost declarate.
Care dintre selectorii din cascadă „câștigă” depinde de trei factori enumerați în ordinea greutății, cu precizarea că primii pot suprascrie pe ultimii:
- Importanța
- Specificitatea
- Ordinea
Originea stylesheet-urilor și nivelul de importanță
Din punct de vedere al originii, există trei tipuri de foi de stil (în ordinea crescătoare a priorității):
- User agent stylesheets — stiluri predefinite de browser. Dacă testați o pagină fără niciun stil definit, veți observa că totuși există anumite stiluri implicite aplicate elementelor (de ex.: link-urile au culoarea albastră). Deoarece nu există o standardizare unanim acceptată de browsere, este recomandată în unele cazuri folosirea unei foi de stil (reset) pentru a porni de la aceeași bază de stiluri în orice browser.
- Author stylesheets — stiluri definite de autorul paginii web (cele incluse în pagină cu link, style și atributul inline style="...").
- User stylesheets — unele browsere oferă utilizatorilor posibilitatea de a suprascrie stilurile paginilor prin aplicarea unor foi de stil peste cele definite de autorii paginilor.
Din punct de vedere al importanței, există două paliere:
- Reguli importante. Regulile importante se remarcă prin prezența declarației !important și au prioritate în fața regulilor normale.
- Reguli normale.
În funcție de origine și importanță, ordinea aplicării regulilor este (în ordinea crescătoare a priorității):
- Reguli la nivel de browser (user-agent stylesheets);
- Reguli cu importanță normală din user stylesheets;
- Reguli cu importanță normală din author stylesheets;
- Reguli importante din author stylesheets;
- Reguli importante din user stylesheets.
Importanța
În sintaxa CSS există un element care poate fi utilizat pentru a vă asigura că o anumită declarație va câștiga întotdeauna: !important.
☞ Valoarea !important se va utiliza doar dacă nu există o altă
soluție, pentru că poate duce la complicarea inutilă a foilor de stil și le face foarte greu de modificat și
întreținut.
Specificitatea
Specificitatea este o modalitate de a măsura „greutatea” unui selector.
După cum am menționat mai sus, dacă două seturi de reguli au aceeași origine și aceeași importanță, ordonarea se face în funcție de specificitate.
Specificitatea se poate calcula astfel:
- Se numără selectorii de ID-uri (
#NumeID) din regulă. - Se numără selectorii de clase (
.NumeClasa) și numărul de pseudo-clase (:hover). Declarația cu numărul total mai mare de astfel de selectori va avea specificitate mai mare. În sfârșit, dacă și acum există egalitate, se trece la ultimul pas. - Se numără selectorii de etichete (
div,p,h1etc.) și pseudo-elementele (::first-letter).
Declarația care întrunește scorul cel mai mare este cea care va fi aplicată, pentru că are cea mai mare specificitate.
Dacă încă există egalitate între declarații, atunci diferența va fi făcută de ordinea în care au fost declarate.
Pentru a ușura procesul de calcul al specificității unui selector, se poate folosi metoda de calcul bazată pe patru valori sau componente: mii, sute, zeci, unități (patru cifre unice în patru coloane).
- Mii - poate avea valoarea 0 (declarațiile sunt în cadrul unui tag
stylesau în fișier extern) sau 1 (declarațiile sunt inline, prin atributulstyleal elementului); - Sute - se acordă un punct pentru fiecare ID conținut în cadrul selectorului general;
- Zeci - se acordă un punct pentru fiecare clasă, atribut selector sau pseudo-clasă din interiorul selectorului general;
- Unități - se acordă un punct pentru fiecare selector de element sau pseudo-element din interiorul selectorului general.
Pentru a înțelege mai bine, să aruncăm o privire peste tabelul de mai jos:
| Selector | Mii | Sute | Zeci | Unități | Total |
|---|---|---|---|---|---|
h1 |
0 | 0 | 0 | 1 | 0001 |
h1 + p::first-letter |
0 | 0 | 0 | 3 | 0003 |
li > a[href*="en-US"] > .warning |
0 | 0 | 2 | 2 | 0022 |
#identifier |
0 | 1 | 0 | 0 | 0100 |
| Niciun selector, inline CSS | 1 | 0 | 0 | 0 | 1000 |
Ordinea sursei
Așa cum am menționat deja, dacă mai mulți selectori concurenți au aceeași importanță și specificitate, al treilea factor care intră în joc pentru a determina regula câștigătoare este source order (ordinea sursei) — ceea ce înseamnă că regulile ulterioare vor bate regulile anterioare.
☞ Un lucru de avut în vedere atunci când ne gândim la teoria cascadei și la regulile care bat alte reguli este că toate acestea se întâmplă la nivel de proprietate — proprietăți care suprascriu alte proprietăți, și nu reguli care înlocuiesc în întregime alte reguli.
Când mai multe reguli CSS țintesc același element, inițial, toate regulile sunt aplicate acelui element. Abia după evaluarea conflictelor se decide care reguli câștigă și vor fi aplicate în final.
Inheritance (moștenirea)
Moștenirea CSS este ultima piesă pe care trebuie să o investigăm pentru a înțelege ce stil este aplicat unui element. Ideea este că unele valori ale proprietății aplicate unui element vor fi moștenite de copiii acelui element, iar altele nu.
De exemplu, are sens ca fontul și culoarea să fie moștenite, deoarece autorul poate seta un font pentru întregul site prin aplicarea lui pe elementul html, urmând ca acesta să fie suprascris doar acolo unde se dorește.
Ar fi neproductiv să fie nevoie să setăm fontul separat pentru fiecare element din site.
Un alt exemplu logic: proprietățile margin, padding, border și
background-image nu sunt moștenite. Dacă acestea ar fi moștenite automat, ar trebui eliminate sau
modificate manual pentru fiecare element copil.
Lista completă a proprietăților moștenite se poate găsi în documentația CSS.
Controlul moștenirii
CSS furnizează patru valori pentru a controla moștenirea:
- inherit — Setează valoarea proprietății aplicate unui element să fie identică cu cea a elementului părinte.
- initial — Setează valoarea proprietății conform foii de stil implicite a browserului. Dacă proprietatea este moștenită natural, se comportă ca inherit.
- unset — Resetează proprietatea la valoarea naturală: dacă e moștenită implicit, acționează ca inherit, altfel ca initial.
- revert — Resetează proprietatea la valoarea pe care ar fi avut-o înainte de a fi suprascrisă.
Dintre acestea, inherit este cea mai utilă când vrem ca un element să moștenească explicit valoarea de la părinte.
Resetarea tuturor valorilor proprietăților
Cu ajutorul proprietății prescurtate all poate fi aplicată oricare dintre valorile de moștenire discutate, aproape tuturor proprietăților simultan. Este o metodă convenabilă pentru a reveni la un „moment zero” înainte de a adăuga noi stiluri.
all: initial;
all: inherit;
all: unset;
all: revert;
În exercițiul următor, încercați să scrieți o singură regulă care să suprascrie proprietățile color și background-color aplicate implicit link-urilor.
🧠 Quiz - CSS Cascada și Moștenirea
