CSS
Kaskadowanie i specyficzność
Szukaj…
Uwagi
Specyfika CSS ma na celu promowanie zwięzłości kodu, pozwalając autorowi zdefiniować ogólne reguły formatowania dla szerokiego zestawu elementów, a następnie zastąpić je dla określonego podzbioru.
Kaskadowe
Kaskadowanie i specyficzność są używane razem w celu ustalenia ostatecznej wartości właściwości stylu CSS. Definiują także mechanizmy rozwiązywania konfliktów w zestawach reguł CSS.
CSS Kolejność ładowania
Style są odczytywane z następujących źródeł, w następującej kolejności:
- Arkusz stylów agenta użytkownika (style dostarczone przez dostawcę przeglądarki)
- Arkusz stylów użytkownika (Dodatkowy styl, który użytkownik ustawił w swojej przeglądarce)
- Arkusz stylów autora (tutaj autor oznacza twórcę strony / witryny)
- Może jeden lub więcej plików
.css
- W elemencie
<style>
dokumentu HTML
- Może jeden lub więcej plików
- Style wbudowane (w atrybucie
style
w elemencie HTML)
Przeglądarka wyszuka odpowiednie style podczas renderowania elementu.
Jak rozwiązywane są konflikty?
Gdy tylko jeden zestaw reguł CSS próbuje ustawić styl dla elementu, nie ma konfliktu i ten zestaw reguł jest używany.
W przypadku znalezienia wielu zestawów reguł z ustawieniami powodującymi konflikt, najpierw stosuje się reguły Specyfika, a następnie Reguły kaskadowe określają, którego stylu należy użyć.
Przykład 1 - Reguły specyficzności
.mystyle { color: blue; } /* specificity: 0, 0, 1, 0 */
div { color: red; } /* specificity: 0, 0, 0, 1 */
<div class="mystyle">Hello World</div>
Jakiego koloru będzie tekst? (najedź, aby zobaczyć odpowiedź)
niebieski
Najpierw stosowane są reguły specyficzności, a ta o najwyższej specyficzności „wygrywa”.
Przykład 2 - Reguły kaskadowe z identycznymi selektorami
Zewnętrzny plik css
.class {
background: #FFF;
}
Wewnętrzny css (w pliku HTML)
<style>
.class {
background: #000;
}
<style>
W tym przypadku, gdy masz identyczne selektory, kaskada rozpoczyna się i określa, że ostatni załadowany „wygrywa”.
Przykład 3 - reguły kaskadowe po regułach specyficzności
body > .mystyle { background-color: blue; } /* specificity: 0, 0, 1, 1 */
.otherstyle > div { background-color: red; } /* specificity: 0, 0, 1, 1 */
<body class="otherstyle">
<div class="mystyle">Hello World</div>
</body>
Jakiego koloru będzie tło?
czerwony
Po zastosowaniu reguł specyficzności nadal występuje konflikt między kolorem niebieskim i czerwonym, więc reguły kaskadowe są stosowane nad regułami specyficzności. Kaskadowanie sprawdza kolejność ładowania reguł, czy to w tym samym pliku .css
, czy w kolekcji źródeł stylów. Ostatni załadowany zastępuje wszystkie wcześniejsze. W tym przypadku .otherstyle > div
„wygrywa”.
Ostatnia uwaga
- Specyfika selektora ma zawsze pierwszeństwo.
- Zerwać powiązania zamówienia arkusza stylów.
- Style wbudowane przebijają wszystko.
! Ważna deklaracja
Deklaracja !important
służy do zastąpienia zwykłej specyficzności w arkuszu stylów przez nadanie regule wyższego priorytetu. Jego użycie to: property : value !important;
#mydiv {
font-weight: bold !important; /* This property won't be overridden
by the rule below */
}
#outerdiv #mydiv {
font-weight: normal; /* #mydiv font-weight won't be set to normal
even if it has a higher specificity because
of the !important declaration above */
}
Zdecydowanie zaleca się unikanie użycia !important
(chyba że jest to absolutnie konieczne), ponieważ zakłóci naturalny przepływ reguł CSS, co może powodować niepewność w arkuszu stylów. Należy również zauważyć, że w przypadku zastosowania wielu !important
deklaracji do tej samej reguły w odniesieniu do określonego elementu, zastosowana zostanie ta o wyższej specyficzności.
Oto kilka przykładów, w których użycie !important
deklaracja może być uzasadniona:
- Jeśli twoje reguły nie powinny być nadpisywane przez dowolny styl wbudowany elementu, który jest zapisany w atrybucie
style
elementu html. - Aby dać użytkownikowi większą kontrolę nad dostępnością w sieci, np. Zwiększając lub zmniejszając rozmiar czcionki, zastępując styl autora za pomocą
!important
. - Do testowania i debugowania przy użyciu elementu inspekcji.
Zobacz też:
Obliczanie swoistości selektora
Każdy indywidualny selektor CSS ma własną wartość specyficzności. Każdy selektor w sekwencji zwiększa ogólną specyficzność sekwencji. Selektory należą do jednej z trzech różnych grup specyficzności: A , B i c . Gdy wiele sekwencji selektorów wybiera dany element, przeglądarka stosuje style zastosowane przez sekwencję o najwyższej ogólnej specyficzności.
Grupa | Składa się z | Przykłady |
---|---|---|
ZA | selektory id | #foo |
b | selektory klas selektory atrybutów pseudoklasy | .bar [title] , [colspan="2"] :hover :nth-child(2) |
do | selektory typu pseudoelementy | div , li ::before , ::first-letter |
Grupa A jest najbardziej specyficzna, następnie Grupa B , a następnie Grupa C.
Selektor uniwersalny ( *
) i kombinatory (jak >
i ~
) nie mają żadnej specyficzności.
Przykład 1: Specyficzność różnych sekwencji selektora
#foo #baz {} /* a=2, b=0, c=0 */
#foo.bar {} /* a=1, b=1, c=0 */
#foo {} /* a=1, b=0, c=0 */
.bar:hover {} /* a=0, b=2, c=0 */
div.bar {} /* a=0, b=1, c=1 */
:hover {} /* a=0, b=1, c=0 */
[title] {} /* a=0, b=1, c=0 */
.bar {} /* a=0, b=1, c=0 */
div ul + li {} /* a=0, b=0, c=3 */
p::after {} /* a=0, b=0, c=2 */
*::before {} /* a=0, b=0, c=1 */
::before {} /* a=0, b=0, c=1 */
div {} /* a=0, b=0, c=1 */
* {} /* a=0, b=0, c=0 */
Przykład 2: W jaki sposób przeglądarka wykorzystuje specyfikę
Wyobraź sobie następującą implementację CSS:
#foo {
color: blue;
}
.bar {
color: red;
background: black;
}
Tutaj mamy selektor identyfikatora, który deklaruje color
jako niebieski , oraz selektor klasy, który deklaruje color
jako czerwony, a background
jako czarny .
Element o identyfikatorze #foo
i klasie .bar
zostanie wybrany w obu deklaracjach. Selektory ID mają specyficzność grupy A, a selektory klasy mają specyficzność grupy B. Selektor identyfikatora przeważa dowolną liczbę selektorów klas. Z tego powodu color:blue;
z selektora #foo
i background:black;
z selektora .bar
zostanie zastosowany do elementu. Większa specyficzność selektora ID spowoduje, że przeglądarka zignoruje deklarację color
selektora .bar
.
Teraz wyobraź sobie inną implementację CSS:
.bar {
color: red;
background: black;
}
.baz {
background: white;
}
Tutaj mamy dwa selektory klas; jeden z nich deklaruje, color
jak czerwony i background
jak czarny, a drugi deklaruje background
jako białe.
Oba te deklaracje będą miały wpływ na element zarówno z .bar
i .baz
, jednak problem, który mamy teraz, polega na tym, że zarówno .bar
jak i .baz
mają identyczną specyfikę grupy B. Kaskadowa natura CSS rozwiązuje to dla nas: ponieważ .baz
jest zdefiniowane po .bar
, nasz element kończy się color
czerwonym z .bar
ale białym background
z .baz
.
Przykład 3: Jak manipulować specyficznością
Ostatnim fragmentem z powyższego przykładu 2 można manipulować w celu zapewnienia, że .bar
naszego selektora klasy .bar
używana jest deklaracja color
.baz
selektora klasy .baz
.
.bar {} /* a=0, b=1, c=0 */
.baz {} /* a=0, b=1, c=0 */
Najczęstszym sposobem osiągnięcia tego jest ustalenie, jakie inne selektory można zastosować do sekwencji selektora .bar
. Na przykład, jeżeli .bar
klasę zawsze tylko stosować do span
elementów mogli modyfikować .bar
selektor span.bar
. Dałoby to nową specyfikę grupy C , która zastąpiłaby .baz
selektora .baz
:
span.bar {} /* a=0, b=1, c=1 */
.baz {} /* a=0, b=1, c=0 */
Jednak nie zawsze możliwe jest znalezienie innego wspólnego selektora, który jest współużytkowany przez dowolny element korzystający z klasy .bar
. Z tego powodu CSS pozwala nam powielać selektory w celu zwiększenia specyficzności. Zamiast tylko .bar
, możemy zamiast tego użyć .bar.bar
(zobacz Gramatyka selektorów, zalecenie W3C ). To nadal wybiera dowolny element z klasą .bar
, ale teraz ma podwójną specyfikę grupy B :
.bar.bar {} /* a=0, b=2, c=0 */
.baz {} /* a=0, b=1, c=0 */
!important
i wbudowane deklaracje stylu
Flaga !important
w deklaracji stylu i style zadeklarowane przez atrybut style
HTML są uważane za mające większą specyfikę niż jakikolwiek selektor. Jeśli takie istnieją, deklaracja stylu, której dotyczą, unieważni inne deklaracje, niezależnie od ich specyfiki. To znaczy, chyba że masz więcej niż jedną deklarację, która zawiera !important
flagę dla tej samej właściwości, która dotyczy tego samego elementu. Następnie do tych właściwości będą miały zastosowanie normalne reguły specyficzności.
Ponieważ całkowicie zastępują one specyficzność, użycie !important
jest lekceważona w większości przypadków użycia. Należy go używać tak mało, jak to możliwe. Aby utrzymać efektywność i łatwość utrzymania kodu CSS na dłuższą metę, prawie zawsze lepiej jest zwiększyć specyficzność otaczającego selektora niż używać !important
.
Jednym z tych nielicznych wyjątków gdzie !important
nie jest mile widziana, jest przy wdrażaniu ogólnych klas pomocników niczym .hidden
lub .background-yellow
klasy, które mają zawsze zastąpić jeden lub więcej właściwości, gdziekolwiek one występują. I nawet wtedy musisz wiedzieć, co robisz. Ostatnią rzeczą, którą chcesz, pisząc możliwy do utrzymania CSS, jest !important
flagi w całym CSS.
Ostatnia uwaga
Powszechnym nieporozumieniem na temat specyficzności CSS jest to, że wartości Grupy A , B i c należy łączyć ze sobą ( a=1, b=5, c=1
=> 151). Tak nie jest. Gdyby tak było, posiadanie 20 selektora grupy B lub c wystarczyłoby, aby zastąpić odpowiednio jeden selektor grupy A lub B. Te trzy grupy należy traktować jako indywidualne poziomy specyficzności. Specyfika nie może być reprezentowana przez pojedynczą wartość.
Tworząc arkusz stylów CSS, powinieneś zachować możliwie najniższą specyfikę. Jeśli chcesz zwiększyć specyficzność, aby zastąpić inną metodę, ustaw ją na wyższą, ale tak niską, jak to możliwe, aby była wyższa. Nie powinieneś mieć takiego selektora:
body.page header.container nav div#main-nav li a {}
To utrudnia przyszłe zmiany i zanieczyszcza stronę css.
Można obliczyć specyfikę swojej selektora tutaj
Bardziej złożony przykład specyficzności
div {
font-size: 7px;
border: 3px dotted pink;
background-color: yellow;
color: purple;
}
body.mystyle > div.myotherstyle {
font-size: 11px;
background-color: green;
}
#elmnt1 {
font-size: 24px;
border-color: red;
}
.mystyle .myotherstyle {
font-size: 16px;
background-color: black;
color: red;
}
<body class="mystyle">
<div id="elmnt1" class="myotherstyle">
Hello, world!
</div>
</body>
Jakie będą granice, kolory i rozmiary czcionek?
rozmiar czcionki:
font-size: 24;
, ponieważ zestaw reguł#elmnt1
ma najwyższą specyfikę dla<div>
mowa, każda właściwość tutaj jest ustawiona.
granica:
border: 3px dotted red;
. Kolor obramowaniared
pochodzi z#elmnt1
reguł#elmnt1
, ponieważ ma najwyższą swoistość. Inne właściwości granicy, grubości i stylu ramki pochodzą z zestawu regułdiv
.
kolor tła:
background-color: green;
.background-color
jest ustawiany wbody.mystyle > div.myotherstyle
div
,body.mystyle > div.myotherstyle
i.mystyle .myotherstyle
. Specyfika to (0, 0, 1) vs. (0, 2, 2) vs. (0, 2, 0), więc środkowa „wygrywa”.
kolor:
color: red;
. Kolor jest ustawiany zarówno w.mystyle .myotherstyle
regułdiv
i.mystyle .myotherstyle
. Ta ostatnia ma wyższą specyficzność (0, 2, 0) i „wygrywa”.