The CSS Podcast - 003: Specificity
Załóżmy, że pracujesz z tym kodem HTML i CSS:
<button class="branding">Hello, Specificity!</button>
.branding {
color: blue;
}
button {
color: red;
}
Tutaj są 2 reguły, które dotyczą tego samego elementu. Każda reguła zawiera deklarację, która ma na celu ustawienie koloru przycisku: jedna próbuje nadać mu kolor czerwony, a druga – niebieski. Która deklaracja zostanie zastosowana do elementu?
Zrozumienie algorytmu specyficzności CSS jest kluczowe, aby zrozumieć, jak CSS podejmuje decyzje między konkurującymi ze sobą deklaracjami.
Szczegółowość to jeden z etapów kaskady, który został omówiony w poprzednim module na temat kaskady.
Ocena specyficzności
Każda reguła selektora w źródle otrzymuje wynik. Specyficzność możesz traktować jako łączną ocenę, a każdy typ selektora zdobywa punkty na jej rzecz. Wygrywają deklaracje z reguł o najwyższej specyficzności.
W przypadku konkretnego projektu musisz zadbać o to, aby reguły CSS, które chcesz zastosować, rzeczywiście się stosowały, a jednocześnie utrzymywać niskie wyniki, aby uniknąć nadmiernej złożoności. Specyficzność powinna być tak wysoka, jak to konieczne, a nie dążyć do jak najwyższej specyficzności. W przyszłości może być konieczne zastosowanie bardziej istotnych reguł CSS. Jeśli spróbujesz uzyskać jak najwyższą specyficzność, utrudnisz sobie pracę.
Specyficzność nie jest liczbą dziesiętną, ale triadą składającą się z 3 składników: A
, B
i C
.
A
: specyficzność identyfikatoraB
: specyficzność podobna do klasyC
: specyfikacja podobna do elementu
Jest on często przedstawiany za pomocą zapisu (A,B,C)
. Na przykład: (1,0,2)
.
Często używana jest też alternatywna notacja A-B-C
.
Porównanie specyfikacji
Specyficzność jest porównywana przez porównanie 3 składników w kolejności: specyficzność z większą wartością A jest bardziej szczegółowa; jeśli 2 wartości A są takie same, specyficzność z większą wartością B jest bardziej szczegółowa; jeśli 2 wartości B są takie same, specyficzność z większą wartością C jest bardziej szczegółowa; jeśli wszystkie wartości są takie same, 2 specyficzności są równe.
Na przykład (1,0,0)
ma większą specyficzność niż (0,4,3)
, ponieważ wartość A
w (1,0,0)
(czyli 1
)
jest większa niż wartość A
w (0,4,3)
(czyli 0
).
Selektory wpływają na szczegółowość
Każda część triady specyficzności zaczyna się od wartości 0
, więc domyślna specyficzność to (0,0,0)
.
Każda część selektora zwiększa specyficzność, która w zależności od typu selektora zwiększa wartość A
, B
lub C
.
Selektor uniwersalny
Selektor uniwersalny (*
)
dodaje brak specyficzności, pozostawiając wartość na początkowej specyficzności (0,0,0)
.
* {
color: red;
}
Selektor elementu lub pseudoelementu
Selektor elementu (typu) lub pseudoelementu dodaje specyficzność podobną do elementu, która zwiększa komponent C
o 1
.
Poniższe przykłady mają ogólną specyficzność (0,0,1)
.
Selektor typu
div {
color: red;
}
Selektor pseudoelementu
::selection {
color: red;
}
Selektor klasy, pseudoklasy lub atrybutu
Selektor klasy, pseudoklasy lub atrybutu dodaje specyficzność podobną do klasy, która zwiększa komponent B
o 1
.
Poniższe przykłady mają specyficzność (0,1,0)
.
Selektor zajęć
.my-class {
color: red;
}
Selektor pseudoklasy
:hover {
color: red;
}
Selektor atrybutów
[href='#'] {
color: red;
}
Selektor identyfikatorów
Selektor identyfikatora dodaje specyficzność podobną do identyfikatora, która zwiększa komponent A
o 1,
o ile używasz selektora identyfikatora (#myID
), a nie selektora atrybutu ([id="myID"]
).
W tym przykładzie specyficzność wynosi (1,0,0)
.
#myID {
color: red;
}
Inne selektory
CSS ma wiele selektorów. Nie wszystkie z nich są szczegółowe.
Na przykład pseudoklasa :not()
nie wpływa w żaden sposób na obliczenie specyficzności.
Jednak selektory przekazane jako argumenty są dodawane do obliczenia specyficzności.
div:not(.my-class) {
color: red;
}
Ta próbka ma specyficzność (0,1,1), ponieważ zawiera jeden selektor typu (div
) i jedną klasę wewnątrz elementu :not()
.
Sprawdź swoją wiedzę
Sprawdź swoją wiedzę na temat punktacji specyficzności
Jaka jest specyfika a[href="#"]
?
(0,1,0)
(0,1,1)
(0,0,1)
Czynniki, które nie wpływają na specyficzność
Oto kilka błędnych przekonań dotyczących czynników wpływających na specyficzność.
Wbudowane atrybuty stylów
CSS zastosowany bezpośrednio do atrybutu style
elementu nie wpływa na specyficzność, ponieważ jest to inny krok w kaskadzie, który jest oceniany przed specyficznością.
<div style="color: red"></div>
Aby zastąpić tę deklarację w arkuszu stylów, musisz uzyskać deklarację zwycięstwa na wcześniejszym etapie kaskady.
Możesz na przykład dodać do niego pole !important
, aby stało się ono częścią autorskiej wersji źródłowej !important
.
!important
deklaracji
Wartość !important
na końcu deklaracji CSS nie ma wpływu na specyficzność, ale umieszcza deklarację w innej źródle, a mianowicie autorskiej !important
.
W poniższym przykładzie szczegółowość .my-class
nie ma znaczenia dla skuteczności deklaracji !important
.
.my-class {
color: red !important;
color: white;
}
Gdy 2 deklaracje są !important
, ponownie bierze się pod uwagę specyficzność, ponieważ krok źródłowy z kaskady nie był jeszcze w stanie określić zwycięzcy.
.branding {
color: blue !important;
}
button {
color: red !important;
}
Specyfika w kontekście
Gdy używany jest selektor złożony lub złożony, każda część tego selektora zwiększa jego szczegółowość. Weź pod uwagę ten przykład kodu HTML:
<a class="my-class another-class" href="#">A link</a>
Ten link dotyczy 2 zajęć.
Reguła w tym kodzie CSS ma specyficzność (0,0,1)
:
a {
color: red;
}
Jeśli w selektorze odwołujesz się do jednej z klas, ma ona teraz specyficzność (0,1,1)
:
a.my-class {
color: green;
}
Dodaj do selektora inną klasę, która ma teraz specyficzność (0,2,1)
:
a.my-class.another-class {
color: rebeccapurple;
}
Dodaj atrybut href
do selektora. Teraz ma on specyficzność (0,3,1)
:
a.my-class.another-class[href] {
color: goldenrod;
}
Na koniec dodaj pseudoklasę :hover
do wszystkich tych elementów. W rezultacie selektor ma specyficzność (0,4,1)
:
a.my-class.another-class[href]:hover {
color: lightgrey;
}
Sprawdź swoją wiedzę
Sprawdź swoją wiedzę na temat punktacji specyficzności
Który z tych selektorów ma specyficzność (0,2,1)
?
article:hover a[href]
article > section
article.card.dark
Praktyczne zwiększanie specyficzności
Załóżmy, że masz kod CSS, który wygląda tak:
.my-button {
background: blue;
}
button[onclick] {
background: grey;
}
Kod HTML wygląda tak:
<button class="my-button" onclick="alert('hello')">Click me</button>
Przycisk ma szare tło, ponieważ drugi selektor ma specyficzność (0,1,1)
.
Dzieje się tak, ponieważ ma jeden selektor typu (button
), który jest (0,0,1)
i selektor atrybutu ([onclick]
), który jest (0,1,0)
.
Poprzednia reguła (.my-button
) jest równa (0,1,0)
, ponieważ ma jeden selektor klasy, który ma niższą specyficzność niż (0,1,1)
.
Jeśli chcesz wzmocnić działanie tej reguły, możesz powtórzyć selektor klasy w ten sposób:
.my-button.my-button {
background: blue;
}
button[onclick] {
background: grey;
}
Przycisk będzie teraz mieć niebieskie tło, ponieważ nowy selektor ma specyficzność (0,2,0)
.
W przypadku remisu w szczegółowości następuje przejście do następnego kroku w kaskadzie.
Na razie pozostańmy przy przykładzie przycisku i zmodyfikujmy kod CSS w ten sposób:
.my-button {
background: blue;
}
[onclick] {
background: grey;
}
Przycisk ma szare tło, ponieważ oba selektory mają identyczną specyficzność (0,1,0)
.
Jeśli przełączysz reguły w kolejności źródłowej, przycisk będzie niebieski.
[onclick] {
background: grey;
}
.my-button {
background: blue;
}
Dzieje się tak, ponieważ oba selektory mają tę samą specyficzność. W takim przypadku kaskada przechodzi do etapu kolejności wyświetlania.