Który styl jest ważniejszy? Skąd ma być pobrany? Poznanie pojęcia „szczegółowości” pozwoli pisać tak zwięzły i szybki kod jak to możliwe.
Zasady według jakich przeglądarka dobiera style strony zwykle są zgodne z oczekiwaniami, ale czasem pojawiają się niespodzianki. Generalna zasada mówi, że najpierw rozpatrywane są najbardziej szczegółowe reguły, a następnie bardziej ogólne. Oczywiście jest to tylko uproszczenie, a zasady dobierania stylów są ustandaryzowane.
Który styl z arkusza zostanie wybrany?
Każda reguła (regułą jest np. „{html}div#menu .top{/html}”) opisana w kaskadowym arkuszu stylów posiada tzw. szczegółowość (ang. specifity), którą można obliczyć na podstawie precyzyjnie określonej zasady, która zostanie opisana poniżej. Przeglądarka oblicza szczegółowość każdej zasady dla każdego elementu. Kiedy dwie lub więcej reguł odnoszą się do tego samego elementu na jego wygląd będzie miała to o większej szczegółowości. Jeśli więcej niż jedna reguła ma najwyższą szczegółowość, to wybierana jest ta, którą zapisano jako ostatnią w arkuszu stylów.
Jak porównać szczegółowości?
Wartość szczegółowości opisana jest w czteropolowej notacji, w której pola zawierają liczby i rozdzielone są przecinkami (np. „1, 2, 3, 4”). Porównanie wartości dwóch reguł odbywa się od strony lewej do prawej. Jeśli na danej pozycji są równe, to przechodzi się w prawo i wybiera tę z większą wartością. Zasada jest taka sama jak przy porównywaniu zwykłych liczb przy założeniu, że „cyfry” nie kończą się na dziewiątce – są nieograniczone. Głównie w tym celu w zapisie stosuje się przecinki. Gdyby nie one mogłyby pojawić się problemy jeśli na którejś pozycji pojawi się liczba większa niż 9.
Kilka przykładów powinno wyjaśnić wszystko:
1, 3, 0, 0 > 1, 2, 9, 9
1, 3, 0, 0 > 1, 2, 999, 9
1, 2, 3, 4 < 1, 2, 4, 3
0, 0, 0, 1 < 0, 0, 1, 0
Jak obliczyć szczegółowość reguły?
Selektor uniwersalny {html}(*){/html} ma szczegółowość równą 0,0,0,0. Tyle też wynosi początkowa wartość każdej reguły. Jeśli w dokumencie HTML pojawi się bezpośrednia definicja stylu danego elementu, to wartość pierwszego pola wynosi 1 (np. {html}
{/html} ma szczegółowość 1,0,0,0).
Drugie pole zwiększa się o jeden za każdym razem, kiedy w regule dotyczącej elementu pojawia się identyfikator. Np. reguła {html}#top #menu #list {...}{/html} będzie miała szczegółowość 0,3,0,0, bo element określono za pomocą trzech identyfikatorów.
W następnym polu zliczane są wszystkie klasy (np. .klasa), pseudoklasy (np. {html}:visited{/html}) i atrybuty (np. [title]). Tak jak w polu z liczbą identyfikatorów, wraz z każdą klasą, pseudoklasą i atrybutem użytym w regule wartość pola wzrasta o jeden.
W czwartym, najmniej istotnym polu znajduje się liczba elementów (np. p) i pseudoelementów (np. :first-letter).
Warto zauważyć, że przeglądarki wspierające CSS3 mogą inaczej ustalić szczegółowość danego elementu niż starsza programy wykorzystujące CSS2. Bierze się to z rozbieżności w akceptowalnych elementach, pseudoklasach i pseudoelementach.
Przykłady
Obok reguł z arkusza stylów opisano ich szczegółowość:
div - 0,0,0,1 (element: div)
div>p - 0,0,0,2 (elementy: div, p)
div>p #top - 0,1,0,2 (identyfikator: #top, elementy: div, p)
div>p #top a.lewy - 0,1,1,3 (identyfikator: #top, klasa: lewy, elementy: div, p, a)
div>p #top a.lewy:visited - 0,1,2,3 (identyfikator: #top, klasa: lewy i pseudoklasa :visited, elementy: div, p, a)
Jeśli więc w arkuszu znajdzie się fragment:
div>p { color: red}
div>p #top a.lewy { color: green }
to zastosowany zostanie bardziej szczegółowa reguła ({html}0,1,1,3 > 0,0,0,2{/html} ), a tekst będzie zielony. Oczywiście dotyczy to tylko elementów, które pasują zarówno do pierwszego i drugiego wzorca. Elementy pasujące tylko do pierwszego wzorca pozostaną czerwone.
Obydwie reguły zastąpi poniższy fragment znajdujący się w kodzie strony:
Liczba klas, elementów i identyfikatorów jest taka sama, ale szczegółowość bezpośrednio wstawionych reguł wynosi 1,0,0,0.
Zagadka: jaki kolor będzie miał tekst opisany w sposób taki jak poniżej?
tekst
Ważni i ważniejsi
Oprócz czteropolowej szczegółowości stosuje się jeszcze dyrektywę {html}!important{/html} (ang. "ważne"), która oznacza, że opisana w ten sposób reguła ma być zastosowana nawet jeśli jej szczegółowość jest mniejsza niż pozostałych zawartych w arkuszu. Specyfikacja CSS (zarówno w wersji 2 jak i 3) pozwala na zastosowanie kilku reguł oznaczonych jako ważne dotyczących danego elementu. W takim przypadku obliczenia są kontynuowane w zwykły sposób. Można to wyobrazić sobie jako dodanie jeszcze jednego pola po lewej stronie i ustawianie w nim jedynki dla reguł z {html}!important{/html} i zera bez nich.
W przykładowym kodzie poniżej uzyskamy niebieski tekst, chociaż szczegółowość wskazuje na co innego. Wszystko przez użycie dyrektywy {html}!important{/html}.
...
niebieski tekst
Który styl użyć?
Szczegółowość precyzuje, którą regułę z arkusza stylów zastosować, ale nie mówi nic o wyborze samego arkusza. Pierwsze pole mówi tylko o tym, że ważniejsze są style zawarte bezpośrednio w ciele strony niż te pochodzące z arkusza (o ile nie stosujemy dyrektywy {html}!important{/html}). Przeglądarki nie zwracają uwagi na to, czy styl znajduje w znaczniku
dokumentu, czy w zewnętrznym pliku, ani w jaki sposób zostały dołączone pliki. Ważne jest ich pochodzenie. Style mogą pochodzić od autora strony, od użytkownika (np. niektóre przeglądarki oferują możliwość definiowania stylów) czy z domyślnego arkusza stylów przeglądarki (np. niebieskie, podkreślone odnośniki). Kolejność rozpatrywania arkuszy jest następująca:
- Deklaracje stylu domyślnego przeglądarki
- Deklaracje użytkownika
- Deklaracje autora dokumentu
- Deklaracje autora dokumentu opatrzone dyrektywą !important
- Deklaracje użytkownika opatrzone dyrektywą !important
Każda deklaracja z ważniejszego miejsca nadpisuje poprzednią. Dzięki temu nie musimy deklarować, że linki mają być podkreślone, a nagłówki nieliniowe i większe niż zwykły tekst.
Załóżmy, że w dokumencie znajduje się element strong. Przykładowa przeglądarka korzysta ze standardowego stylu i pogrubia tekst w tym tagu ({html}font-weight: 700{/html}). Autor strony uznaje jednak, że zamiast pogrubiać tekst pisany silną emfazą, będzie on czerwony, ale o zwykłej wadze ({html}font-weight: 400{/html}). Użytkownik korzysta z przeglądarki, która pozwala mu na zmianę stylów odwiedzanych stron. Może więc dopisać sobie regułę, która ponownie pogrubi elementy oznaczone jako strong ( strong {{html}font-weight: 700 !important}{/html} ), a cały tekst ma być czarny ( {html}* {color: black !important }{/html} ). Bez zastosowania dyrektywy {html}!important{/html} jego deklaracje nie odniosłyby skutku.
Znając sposób obliczania szczegółowości nie tylko unikniemy pomyłek i frustracji spowodowanej tym, że styl z jakiegoś powodu nie chce działać, ale możemy też zastosować zasadę mówiącą o użyciu jak najmniejszej liczby selektorów jak to możliwe. Przyśpieszy to proces renderowania strony i z pewnością spodoba się odwiedzającym.