# 20. Stopień ważności selektorów CSS

W poprzednich częściach kursu CSS dowiedzieliśmy się w jaki sposób reguły CSS łączą się ze sobą. Dowiedzieliśmy się również w jaki sposób właściwości CSS nadpisują się, w przypadku gdy w kodzie HTML znajduje się więcej reguł CSS odnoszących się do tego samego elementu HTML oraz posiadających te same właściwości CSS o różnych wartościach. Wspomniane zagadnienia były w miarę proste do zrozumienia, ponieważ reguły CSS były zbudowane z tej samej liczby selektorów CSS, o tym samym stopniu ważności.

W tej części kursu CSS zapoznamy się z regułami CSS zbudowanymi z większej liczby selektorów o różnych stopniach ważności.\
\
Aby zrozumieć stopień ważności selektorów CSS musimy znać grupy ważności na jakie dzielą się selektory CSS, ponieważ każda taka grupa posiada swój własny stopień ważności.\
\
Wspomniane grupy ważności możemy określić za pomocą pomocniczych oznaczeń, np. G1, G2, G3.

**G1 - najwyższy stopień ważności**

*Do tej grupy selektorów CSS należy tylko jeden selektor, a jest nim selektor identyfikatora, np. `#moj_p`*

**G2 - średni stopień ważności**

*Do tej grupy selektorów CSS należą selektory atrybutu, selektory pseudoklasy oraz selektor klasy, np. `.moj_p`*

**G3 - najniższy stopień ważności**

*Do tej grupy selektorów CSS należą selektory pseudoelementu oraz selektor elementu, np. `p`*

**Znaki niewpływające na stopień ważności**

*Następujące znaki, nie wpływają na stopień ważności selektorów CSS: `*`, `,`, `>`, `+`, `~` oraz spacja, która określa selektor potomka*

Gdy utworzymy kilka reguł CSS, które będą posiadały te sama właściwości CSS i które będą odnosiły się do tego samego elementu HTML, oraz które będą zbudowane z różnych typów selektorów CSS, to przeglądarka internetowa dokona selekcji właściwości CSS, przeznaczonych dla danego elementu HTML, na podstawie stopnia ważności selektorów danej reguły CSS.\
\
To tyle, jeżeli chodzi o dość zawiłe zależności. Czas na trochę praktyki.\
\
Przyjrzyjmy się następującemu dokumentowi HTML, a raczej spójrzmy na kod HTML, jaki został w nim umieszczony:

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Darmowy Kurs CSS</title>

    <style>
      p {
        background-color:lightblue;
        padding:15px;
        border:1px solid black;
      }

      #moj_p {
        background-color:gold;
      }
    </style>
  </head>

  <body>

    <div id="moj_div">
      <p id="moj_p" class="moj_p">to jest przykładowy element - p</p>
    </div>

  </body>
</html>
```

Na podstawie informacji, jakie do tej pory zostały przedstawione w poprzednich częściach kursu CSS, możemy wywnioskować, że po wyświetleniu danego dokumentu HTML, w oknie przeglądarki internetowej, ujrzymy element `p`, który będzie posiadał w sobie marginesy wewnętrzne `padding` oraz obramowanie `border`, jak również kolor tła `background-color`.

<figure><img src="https://3876702757-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8htinEZYbP2Js3yNtq9f%2Fuploads%2FZh0EgXXQtiAdA1zVnKLd%2Fimage.png?alt=media&#x26;token=c96fdacc-c351-495d-96d0-686713864cab" alt=""><figcaption></figcaption></figure>

Kolor tła elementu `p` będzie złoty, jednak nie dlatego że reguła utworzona za pomocą selektora `#moj_p` znajduje się po regule utworzonej za pomocą selektora `p`, a dlatego że selektor `#moj_p` ma wyższy stopień ważności od selektora `p`.\
\
Spójrzmy jak będzie wyglądał nasz przykładowy element `p`, gdy zmienimy kolejność reguł CSS w naszym kodzie HTML:

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Darmowy Kurs CSS</title>

    <style>
      #moj_p {
        background-color:gold;
      }

      p {
        background-color:lightblue;
        padding:15px;
        border:1px solid black;
      }
    </style>
  </head>

  <body>

    <div id="moj_div">
      <p id="moj_p" class="moj_p">to jest przykładowy element - p</p>
    </div>

  </body>
</html>
```

Rezultat:

<figure><img src="https://3876702757-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8htinEZYbP2Js3yNtq9f%2Fuploads%2FduJnVUqBRORToaWrPRks%2Fimage.png?alt=media&#x26;token=71ac140e-cd24-443a-a1f4-a1370e9b68e0" alt=""><figcaption></figcaption></figure>

Rezultat jest taki sam jak w poprzednim przykładzie, mimo że reguła CSS utworzona za pomocą selektora `p` została umieszczona po regule CSS, która została utworzona za pomocą selektora `#moj_p`.\
\
Mogłoby się nam wydawać, że kolor tła elementu `p` będzie jasnoniebieski (`lightblue`), jednak wcale tak nie jest, ponieważ jest on złoty (`gold`), a więc reguła CSS utworzona za pomocą selektora `p` oraz posiadająca w sobie, między innymi właściwość `background-color:lightblue;` nie nadpisała właściwości `background-color:gold;` która została umieszczona w regule CSS utworzonej za pomocą selektora `#moj_p`.\
\
Dlaczego tak się dzieje?\
\
Ponieważ przeglądarka internetowa "widząc", że kilka reguł CSS, które posiadają te same właściwości CSS (w naszym przykładzie tą właściwością jest właściwość `background-color`), oraz które odnoszą się do tego samego elementu HTML (w naszym przykładzie tym elementem jest element `p`), dokonuje ona selekcji na podstawie stopnia ważności danej reguły CSS. Stopień ważności reguły CSS jest uzależniony od stopnia ważności selektorów CSS, które tworzą daną regułę CSS.\
\
Właściwości CSS użyte w regułach CSS, które zostały utworzone za pomocą selektorów CSS, które posiadają niższy stopień ważności, nie mogą nadpisać tych samych właściwości CSS, które zostały użyte w regułach CSS utworzonych za pomocą selektorów o wyższym stopniu ważności. W tym wypadku nie ma znaczenia, w jakiej kolejności umieściliśmy nasze reguły CSS, w kodzie HTML, czy też w kodzie osobnego pliku CSS.\
\
W naszym przykładzie występują dwie reguły CSS. Pierwsza z nich, czyli `#moj_p`, została utworzona za pomocą selektora identyfikatora, który należy do grupy G1, a więc posiada w sobie najwyższy stopień ważności. Natomiast druga reguła CSS, czyli `p`, została utworzona za pomocą selektora elementu, który należy do grupy G3, a więc posiada w sobie najniższy stopień ważności. Dlatego też reguła CSS utworzona za pomocą selektora `p` nie może nadpisać właściwości CSS występujących w regule CSS, która została utworzona za pomocą selektora `#moj_p`.\
\
Spójrzmy teraz na nieco inną sytuację w naszym dokumencie HTML:

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Darmowy Kurs CSS</title>

    <style>
      p#moj_p {
        background-color:gold;
      }

      #moj_p {
        background-color:lightblue;
        padding:15px;
        border:1px solid black;
      }
    </style>
  </head>

  <body>

    <div id="moj_div">
      <p id="moj_p" class="moj_p">to jest przykładowy element - p</p>
    </div>

  </body>
</html>
```

Rezultat:

<figure><img src="https://3876702757-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8htinEZYbP2Js3yNtq9f%2Fuploads%2FHaigREq4xXCs0JsuLw1I%2Fimage.png?alt=media&#x26;token=b24f232f-cf04-4b79-abf0-16aa253a14c3" alt=""><figcaption></figcaption></figure>

Kolor tła w elemencie `p` jest złoty (`gold`), a nie jasnoniebieski (`lightblue`). Tym razem nasze reguły CSS zostały utworzone za pomocą selektora `p#moj_p` oraz `#moj_p`.\
\
Przeglądarka "widząc", że w naszym kodzie znajdują się reguły CSS odnoszące się do tego samego elementu HTML, zacznie ona sprawdzać stopień ważności danych reguł CSS, na podstawie stopnia ważności ich selektorów CSS.\
\
W pierwszej kolejności zostanie podjęta próba sprawdzenia czy w regułach CSS został użyty selektor identyfikatora, który posiada najwyższy stopień ważności, ponieważ należy on do grupy G1.\
\
W naszym przykładzie obie reguły CSS posiadają wspomniany selektor identyfikatora (jest to `#moj_p`), w tej samej liczbie (po jednym dla każdej reguły CSS), dlatego przeglądarka internetowa w tym momencie nie będzie mogła określić, tylko na podstawie selektora CSS należącego do grupy G1, która reguła CSS jest bardziej ważna.\
\
W następnej kolejności zostanie podjęta próba sprawdzenia czy w regułach CSS został użyty jakiś selektor, który posiada średni stopień ważności, a więc taki, który należy do grupy G2.\
\
W naszym przykładzie obie reguły CSS nie posiadają w sobie selektorów należących do grupy G2, dlatego przeglądarka internetowa w tym momencie nie będzie mogła określić, która reguła CSS jest bardziej ważna.\
\
W następnej kolejności zostanie podjęta próba sprawdzenia czy w regułach CSS został użyty jakiś selektor, który posiada najniższy stopień ważności, a więc taki, który należy do grupy G3.\
\
W naszym przykładzie reguła `p#moj_p` posiada w sobie selektor elementu (jest to `p`), który należy do grupy G3, dlatego to właśnie reguła `p#moj_p` będzie bardziej "ważną" regułą CSS, a nie reguła `#moj_p`.\
\
A o to nieco inna sytuacja:

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Darmowy Kurs CSS</title>

    <style>
      p#moj_p {
        background-color:gold;
      }

      #moj_p.moj_p {
        background-color:lightblue;
        padding:15px;
        border:1px solid black;
      }
    </style>
  </head>

  <body>

    <div id="moj_div">
      <p id="moj_p" class="moj_p">to jest przykładowy element - p</p>
    </div>

  </body>
</html>
```

Rezultat:

<figure><img src="https://3876702757-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8htinEZYbP2Js3yNtq9f%2Fuploads%2FO6BggQsK84C9RM19Lnp0%2Fimage.png?alt=media&#x26;token=e84ae3d2-66c5-412c-b96d-90d868f62015" alt=""><figcaption></figcaption></figure>

Tym razem bardziej ważną regułą CSS będzie reguła `#moj_p.moj_p`, a nie reguła `p#moj_p`, ponieważ obie reguły CSS posiadają w sobie tą samą liczbę selektorów identyfikatora, lecz reguła `#moj_p.moj_p` jest dodatkowo zbudowana za pomocą selektora klasy (czyli `.moj_p`), który należy do grupy G2, natomiast reguła `p#moj_p` nie posiada w sobie żadnego selektora należącego do grupy G2 i właśnie dlatego kolor tła elementu `p` jest jasnoniebieski (`lightblue`), a nie złoty (`gold`).\
\
Następny przykład:

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Darmowy Kurs CSS</title>

    <style>
      #moj_div > #moj_p {
        background-color:lightblue;
        padding:15px;
        border:1px solid black;
      }

      p#moj_p.moj_p:first-child {
        background-color:gold;
      }
    </style>
  </head>

  <body>

    <div id="moj_div">
      <p id="moj_p" class="moj_p">to jest przykładowy element - p</p>
    </div>

  </body>
</html>
```

Rezultat:

<figure><img src="https://3876702757-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8htinEZYbP2Js3yNtq9f%2Fuploads%2FCFvzkvmxksghKdGcXpXY%2Fimage.png?alt=media&#x26;token=7a2a3b17-b2ca-491a-94f2-db04a7a23c46" alt=""><figcaption></figcaption></figure>

Tym razem w dość łatwy sposób możemy określić, która reguła CSS jest bardziej ważna. Bardziej ważną regułą CSS będzie reguła `#moj_div > #moj_p`, ponieważ jest ona zbudowana z dwóch selektorów identyfikatora (czyli `#moj_div` oraz `#moj_p`), które należą do grupy G1, natomiast reguła `p#moj_p.moj_p:first-child` jest zbudowana tylko z jednego selektora identyfikatora (czyli `#moj_p`), który należy do grupy G1.\
\
Uwaga Jeżeli reguły CSS odnoszące się do tego samego elementu HTML były by zbudowane w tej samej liczbie z selektorów należących do grupy: G1, G2 lub G3, to ważniejszą regułą CSS będzie ta reguła, która została umieszczona "niżej" w kodzie HTML.\
\
Przykład:

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Darmowy Kurs CSS</title>

    <style>
      /* G1 - #moj_div, G2 - .moj_p, G3 - p */
      #moj_div > p.moj_p {
        background-color:lightblue;
        padding:15px;
        border:1px solid black;
      }

      /* G1 - #moj_p, G2 - :first-child, G3 - p */
      p#moj_p:first-child {
        background-color:gold;
      }
    </style>
  </head>

  <body>

    <div id="moj_div">
      <p id="moj_p" class="moj_p">to jest przykładowy element - p</p>
    </div>

  </body>
</html>
```

Rezultat:

<figure><img src="https://3876702757-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8htinEZYbP2Js3yNtq9f%2Fuploads%2FGztsXhm6FlsBQaPyJeqk%2Fimage.png?alt=media&#x26;token=786c023d-41fe-4cfa-ad9b-9109edd9c8b1" alt=""><figcaption></figcaption></figure>

W kolejnej części kursu CSS poznamy do czego służy deklaracja !important, dzięki której będziemy mogli "łamać" zasady, które do tej pory poznaliśmy.
