Webdesign

Selektory CSS – ID vs CLASS

W tym wpisie poruszymy kwestię selektorów CSS, a konkretnie czy lepiej odwoływać się do poszczególnych elementów HTML za pomocą klas, czy może identyfikatorów? Jedno…

W tym wpisie poruszymy kwestię selektorów CSS, a konkretnie czy lepiej odwoływać się do poszczególnych elementów HTML za pomocą klas, czy może identyfikatorów? Jedno jest pewne. Nie jest to sprawa bez znaczenia.

Na przestrzeni lat widziałem wiele różnych podejść innych osób do odwoływania się w kodzie CSS do elementów HTML. Sam też z różnych podejść korzystałem, by ostatecznie zrozumieć, że identyfikatory w kodzie CSS są absolutnie zbędne. Ba, są często szkodliwe! Wpis ten potraktuj jako moje prywatne zdanie, poparte jednak poniższymi dowodami, które być może przekonają Cię, że znaczek hasha w CSS nie jest Ci potrzebny. Zauważ, że nie powiedziałem „identyfikator nie jest Ci potrzebny”. No właśnie, id ma swoje zastosowanie i jako atrybut na pewno nie zniknie, ale o tym za chwilę.

Specyficzność selektorów CSS

Spójrzmy na poniższy kod HTML:

<p>
    <a href="#">Link</a>
</p>

oraz kod CSS:

a {
    color: red;
}

p a {
    color: blue;
}

Jak zapewne wiesz, ostatecznie element a wyświetli się w kolorze niebieskim, z uwagi na większą specyficzność drugiego selektora (nie jego kolejność w kodzie). O ile powyższy zapis jest oczywisty i „tak właśnie ma być”, to kiedy do akcji wkraczają atrybuty class oraz id, sprawy często się komplikują:

<div id="sidebar">
  <a href="">Treść linku</a>
  
  <p class="small">
    <a href="#" class="button">Przycisk</a>
  </p>
</div>
#sidebar a {
  color: red;
}

p.small .button {
  color: blue;
}

W powyższym przykładzie ustawiamy kolor dla wszystkich linków znajdujących się w sidebarze na czerwony, ale później zdecydowaliśmy, że dodamy do sidebara przygotowany i ostylowany przycisk z klasą button. O ile pojedynczy selektor .button nie wygra, a tym samym jego właściwość color: blue nie zostanie zaaplikowana, to wydawałoby się, że gdy podamy p.small .button to kolor niebieski pojawi się na stronie. Niestety nie.

Sytuacja zmieni się jednak, gdy zrezygnujemy z identyfikatora sidebar na rzecz klasy o tej samej wartości. Wówczas wszystko będzie ok.

To tylko prosty przykład, który obrazuje jednak, że id może utrudniać nam życie. W realnych projektach przysparza nie lada problemów, gdy serwis rośnie i dopisujemy do niego kolejne moduły.

Klas można używać wieloktornie

Jeśli elementowi przypiszemy klasę, to będzie ona dostępna dla wielu elementów. ID jest zarezerwowane dla wyłącznie jednego elementu, a więc i style do niego przypisane są „jednorazowe”. Nawet jeśli sądzisz, że pewien element jest unikalny i jego kod CSS nie będzie nigdy używany dla innych elementów, możesz się mylić. Po pierwsze jest duża szansa, że wpadniesz w kłopoty ze specyficznością opisane wyżej, a po drugie być może skończysz z kopiowaniem raz napisanego kodu CSS dla innego elementu, który pojawi się w przyszłości.

Korzystajmy zatem z zasady DRY czyli Don’t repeat yourself i jeśli pewne elementy mają wspólny kod CSS, to wypiszmy go w jednym miejscu, a różnice przypisujmy do innych klas. Tutaj dobrym przykładem może być moduł komunikatów na stronie. Mamy komunikat informujący o błędzie, następnie o powodzeniu i do tego np. komunikat neutralny. Korzystając z dwóch klas dla każdego elementu, zaoszczędzimy powtórzeń, a nasz kod będzie łatwy w utrzymaniu:

<div class="alert success">
  <p>Komunikat o powodzeniu.</p>
</div>

<div class="alert info">
    <p>Komunikat neutralny.</p>
</div>

<div class="alert warning">
  <p>Komunikat o błędzie</p>
</div>
.alert {
  padding: 10px 20px;
  border-width: 1px;
  border-style: solid;

  font-size: 14px;
  line-height: 18px;
}

.alert.success {
  border-color: green;
  background-color: #CFC;

  color: green;
}

.alert.info {
  border-color: #1B91D3;
  background-color: #BFEDFF;

  color: #1B91D3;
}

.alert.warning {
  border-color: red;
  background-color: #FCC;

  color: red;
}

Choć klasy świetnie nadają się dla elementów, które występują wielokrotnie, nic nie stoi na przeszkodzie, aby przypisać je tylko do jednego elementu, jak wyżej w przypadku sidebara. Nawet jeśli na stronie nie będzie więcej elementów HTML z tą klasą, to do tego jednego będziemy mogli się odwołać, a zagnieżdżone w nim inne elementy nie będą przegrywać ze zbyt dużą specyficznością, jaką generuje identyfikator.

Głębokie zagnieżdżanie i przestrzeń nazw

Porzucenie identyfikatorów na rzecz klas, nie rozwiązuje jednak wszystkich problemów ze specyficznością. Jeśli selektory zagnieżdżamy zbyt głęboko, również będziemy mieli problem. Dobra praktyka mówi, aby starać się nie zagnieżdżać dalej niż 3 poziomy. Tzn, że lepiej napisać .content .header a { color: red; } niż .content .header h2 a span { color: red; }

Przestrzeń nazw jest ważna, bo często na stronie występują te same klasy, ale zupełnie inne style CSS. Jeśli napiszemy .content .button { } oraz .sidebar .button { }, a dodatkowo nigdzie nie pojawi się po prostu .button { }, to mamy 2 zupełnie inne klasy, które nic po sobie nie dziedziczą.

Jeśli piszesz kod HTML, który pojawi się na stronie, gdzie będą np. wgrywane dodatkowe pluginy i martwisz się, że ktoś użył takiej samej klasy jak Ty i Twoje elementy będą z niej pewne właściwości CSS dziedziczyć, to dobrą praktyką jest dodanie do wszystkich swoich klas przedrostka, np. z nazwą pisanego szablonu: .myTheme-button.

Co zatem z identyfikatorami?

Nadal mają swoje zastosowanie! Jedno z nich to kotwice, a zatem przenoszenie użytkownika od razu do danej sekcji strony, np. http://twojastrona.pl/o-nas.html#historia-firmy

Wówczas np. do elementu section przypisujemy id="historia-firmy", ale jeśli chcemy przypisać do niego style, to dodajmy jeszcze klasę CSS, poprzez którą to zrobimy. Nie poprzez dodane ID.

Druga, bardzo ważna rola identyfikatorów, to odwoływanie się do elementów HTML w kodzie JavaScript. Bardzo często jest tak, że interesuje nas wyłącznie jeden, specyficzny element, np. pole input. Fakt, można się do niego odwołać np. poprzez jego rodzica:

document.querySelector("form input");

natomiast dużo lepszym rozwiązaniem jest dodanie do elementu input identyfikatora i odwołanie się bezpośrednio poprzez:

document.querySelector("#name");

Jeśli jednak owemu elementowi chcemy przypisać style (które najprawdopodobniej będą również dla pozostałych pól tego typu), to dodajmy do niego klasę np. „text-field„.

Dlaczego id w takich sytuacjach aż tak się przydaje? Wyobraź sobie, że edytujesz napisany przez kogoś innego kod, np. szablonu jakiegoś systemu e-commerce (1). Kod HTML utrudnia Ci stworzenie layoutu zgodnie z przygotowanym przez designera projektem, zatem go edytujesz. Usuwasz dziwne znaczniki i wybrane pole input wstawiasz w odpowiednim miejscu. Dopisujesz style CSS i pozornie wszystko jest ok. Problem pojawia się natomiast krok dalej, bo okazuje się, że po tym jak użytkownik wpisał swoje dane adresowe, nie zostały przedstawione mu spodziewane sposoby wysyłki, które miały wczytać się za pomocą AJAXa.

Czyżbyś popełnił błąd? Nie, to developer piszący szablon zrobił to źle, bo chwilę później znajdujesz w kodzie JavaScript odwołanie do elementu input w takim stylu „table.shippingAdress tr td input.text-field„. Czy nie byłoby prościej, gdyby ów developer przypisał do pola identyfikator, do którego odwołałby się bezpośrednio? Owszem. Ty musiałbyć wówczas zadbać jedynie o to, by przy edycji nie zmieniać identyfikatorów przypisanych do elementów. W takich sytuacjach najlepiej nie zmieniać również klas, a ewentualnie dopisywać nowe, bo i po klasach często odwołujemy się do wielu elementów w kodzie JavaScript.

Podsumowanie

Jak zatem widzisz, powinniśmy unikać używania identyfikatorów w kodzie CSS. Nie zawsze jest to możliwe, bo czasem nie mamy dostępu do plików z kodem HTML i nie możemy do pewnych elementów dodać własnych klas CSS, a pisanie dziwnych selektorów wybierających konkretny element np. poprzez :nth-child(5) może w przyszłości przysporzyć problemów. Wówczas musimy użyć odwołania po identyfikatorze. Jeśli jednak nie musisz, polecam, abyś tego nie robił.

Jeśli tworzony element HTML będzie poddawany manipulacjom z poziomu kodu JavaScript – przypisz do niego zarówno id jak i klasę. Po klasie ostyluj wygląd, a po id wyszukaj element w drzewie DOM.

Jeśli masz inne zdanie na temat używania w kodzie CSS selektorów z identyfikatorem, napisz w komentarzu!

Ciekawostka

Jakiś czas temu w przeglądarkach opartych na silniku WebKit występował bug, który pozwalał wieloma klasami nadpisać style identyfikatora. Mówiąc wieloma, mam na myśli minimum 256 klas CSS, które należało przypisać do elementu HTML, a następnie wstawić w kodzie CSS łącząc kropką .class1.class.2.class3 itd. Wówczas podany w nich kolor np. niebieski wygrywał z #text { color: red; }

1 historia prawdziwa 🙂

UDOSTĘPNIJ ARTYKUŁ:

Powiązane artykuły

Marketing i Biznes

10 portali dla designerów – cz. II

Darmowe

10 portali dla designerów – część I

Nowości

Black Friday 2018 – najlepsze promocje

Pozostań na bieżąco!

Już nigdy nie przegapisz ważnych informacji, promocji oraz nowych kursów. Zapisz się na newsletter już teraz!

Zapisując się do newslettera akceptujesz naszą politykę prywatności