Zgodność ze specyfikacją

Podcast o CSS – 003: specyficzność

Załóżmy, że pracujesz z takim kodem HTML i CSS:

<button class="branding">Hello, Specificity!</button>
button {
  color: red;
}

.branding {
  color: blue;
}

Istnieją dwie konkurujące ze sobą reguły. Jeden przycisk pokoloruje przycisk na czerwony, a drugi na niebieski. Która reguła jest stosowana do elementu? Zapoznanie się z algorytmem specyfikacji CSS dotyczącym specyfiki jest kluczem do zrozumienia, w jaki sposób CSS decyduje o stosunku do reguł konkurujących.

Szczegółowość to jeden z 4 różnych etapów kaskady, które omówiliśmy w ostatnim module, czyli kaskadzie.

Ocena specyficzności

Każda reguła selektora otrzymuje punktację. Szczegółowość można traktować jako całościowy wynik, w ramach którego za każdy rodzaj selektora naliczane są punkty. Wygrywa selektor z najwyższym wynikiem.

W przypadku precyzyjnego projektu równowaga polega na tym, by zagwarantować, że reguły CSS, które spodziewasz się zastosować, faktycznie są stosowane, przy jednoczesnym utrzymywaniu wyników na niskim poziomie, aby uniknąć złożoności. Wynik powinien być maksymalnie wysoki, a nie najwyższy, możliwy do osiągnięcia. W przyszłości konieczne może być zastosowanie naprawdę ważniejszych usług porównywania cen. Jeśli osiągniesz najwyższy wynik, to będzie ciężka praca.

Ocena każdego typu selektora

Punkty są przyznawane za każdy typ selektora. Dodajesz wszystkie te punkty, aby obliczyć ogólną specyficzność selektora.

Selektor uniwersalny

Selektor uniwersalny (*) nie ma specyfiki i otrzymuje 0 punktów. Oznacza to, że każda reguła z co najmniej 1 punktem zastąpi ją

* {
  color: red;
}

Selektor elementu lub pseudoelementu

Selektor elementu (typu) lub pseudoelementu uzyskuje 1 punkt precyzji .

Wybór typu

div {
  color: red;
}

Selektor pseudoelementów

::selection {
  color: red;
}

Selektor klasy, pseudoklasy lub atrybutu

Selektor klasy, pseudoklasy lub atrybutu uzyskuje 10 punktów szczegółowości.

Selektor zajęć

.my-class {
  color: red;
}

Selektor pseudoklasy

:hover {
  color: red;
}

Selektor atrybutu

[href='#'] {
  color: red;
}

Sama pseudoklasa :not() nie wnosi niczego do obliczenia specyfiki. Jednak selektory przekazywane jako argumenty są dodawane do obliczania specyficzności.

div:not(.my-class) {
  color: red;
}

Ten przykład miałby 11 punktów specyficzności, ponieważ ma 1 selektor typu (div) i 1 klasę wewnątrz :not().

Selektor identyfikatora

Selektor identyfikatora zapewnia 100 szczegółów, o ile używany jest selektor identyfikatora (#myID), a nie selektor atrybutu ([id="myID"]).

#myID {
  color: red;
}

Atrybut stylu wbudowanego

CSS zastosowany bezpośrednio do atrybutu style elementu HTML uzyskuje wynik specyficzności wynoszący 1000 punktów. Oznacza to, że aby zastąpić go w CSS, musisz napisać bardzo szczegółowy selektor.

<div style="color: red"></div>

!important reguła

Wreszcie !important na końcu wartości CSS uzyskuje wynik specyficzności wynoszący 10 tys. punktów. Jest to najwyższa szczegółowość, jaką można uzyskać w przypadku pojedynczego produktu.

Reguła !important jest stosowana do właściwości CSS, więc wszystko w regule ogólnej (selektor i właściwości) nie ma takiego samego wyniku specyfikacji.

.my-class {
  color: red !important; /* 10,000 points */
  background: white; /* 10 points */
}

Sprawdź swoją wiedzę

Sprawdź swoją wiedzę o ocenie szczegółowości

Jaki jest wynik specyficzny a[href="#"]?

1
Wartość a jest warta 1 punkt, [href="#"] – 10 punktów.
5
Spróbuj jeszcze raz.
11
a jest wart 1 punkt, a [href="#"] – 10 punktów, co daje łączny wynik 11 punktów.

Szczegółowość w kontekście

Szczegółowość każdego selektora pasującego do elementu jest sumowana. Przeanalizuj ten przykładowy kod HTML:

<a class="my-class another-class" href="#">A link</a>

Ten link zawiera 2 zajęcia. Po dodaniu tego kodu CSS uzyskasz 1 punkt precyzji:

a {
  color: red;
}

Odwoływanie się do jednej z klas w tej regule ma teraz 11 punktów precyzji:

a.my-class {
  color: green;
}

Gdy dodasz do selektora kolejną klasę, ma ona teraz 21 szczegółów:

a.my-class.another-class {
  color: rebeccapurple;
}

Dodaj do selektora atrybut href, ma on teraz 31 szczegółów:

a.my-class.another-class[href] {
  color: goldenrod;
}

Na koniec dodaj do tych wszystkich pseudoklasę :hover, co spowoduje uzyskanie 41 szczegółów:

a.my-class.another-class[href]:hover {
  color: lightgrey;
}

Sprawdź swoją wiedzę

Sprawdź swoją wiedzę o ocenie szczegółowości

Który z tych selektorów jest wart 21 punktów?

article > section
Elementy są warte 1 punkt, a selektor zawiera 2 elementy, co daje wartość 2 punktów.
article.card.dark
Elementy są warte 1 punkt, klasa 10 punktów, a 2 klasy i 1 element sprawiają, że ten selektor ma 21 punktów.
article:hover a[href]
Elementy są warte 1 punkt, pseudoklasy i atrybuty – 10 punktów, 2 punkty za elementy oraz 20 punktów za atrybuty i klasy. Dlatego ten selektor ma 22 punkty.

Wizualizacja specyficzności

Na diagramach i kalkulatorach specyficzności specyficzność jest często wizualizowana w ten sposób:

Diagram przedstawiający selektory od najbardziej do najmniej szczegółowych

Lewa grupa to selektory id. Druga grupa to selektory klasy, atrybutu i pseudoklasy. Ostatnia grupa to selektory elementów i pseudoelementów.

Oto selektor: 0-4-1:

a.my-class.another-class[href]:hover {
  color: lightgrey;
}

Sprawdź swoją wiedzę

Sprawdź swoją wiedzę na temat wizualizacji specyfiki

Który z tych selektorów to 1-2-1?

section#specialty.dark
Ten selektor jest przedstawiony jako 1-1-1.
#specialty:hover li.dark
🎉
[data-state-rad].dark#specialty:hover
Ten selektor jest przedstawiony jako 1-3-0.
li#specialty section.dark
Ten selektor jest przedstawiony jako 1-1-2.

Pragmatyczne zwiększanie specyficzności

Załóżmy, że mamy taki kod CSS:

.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 uzyskuje 11 punktów szczegółowych (0-1-1). Dzieje się tak, ponieważ ma jeden selektor typu (button), który wynosi 1 punkt i selektor atrybutu ([onclick]), który daje 10 punktów.

Poprzednia reguła – .my-button – otrzymuje 10 punktów (0-1-0), ponieważ ma 1 selektor klasy.

Jeśli chcesz wzmocnić tę regułę, powtórz selektor klasy w ten sposób:

.my-button.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

Teraz przycisk będzie miał niebieskie tło, ponieważ nowy selektor ma wynik specyficzności wynoszący 20 punktów (0-2-0).

Wynik specyficzności dopasowania oznacza najnowszą wygraną instancji

Pozostańmy przy przykładowym przycisku i zmieńmy kod CSS na taki:

.my-button {
  background: blue;
}

[onclick] {
  background: grey;
}

Przycisk ma szare tło, ponieważ oba selektory mają identyczny wynik specyficzności (0-1-0).

Jeśli zmienisz reguły w kolejności źródłowej, przycisk stanie się niebieski.

[onclick] {
  background: grey;
}

.my-button {
  background: blue;
}

Jest to jedyna sytuacja, w której wygrywa nowsza wersja CSS. Aby tak się stało, musi on pasować do specyfiki innego selektora, który jest kierowany na ten sam element.

Zasoby