Budowa arkusza stylów cz. 2. Selektory

Selektor to ta część definicji stylu, która pojawia się przed nawiasem klamrowym, wewnątrz którego znajduje się lista własności i ich wartości (zob. poprzedni artykuł cyklu). Jak sama nazwa mówi, selektor wskazuje i wybiera do oznaczenia pewien element języka opisu dokumentu. Selektory mogą być całkiem proste, ale mogą przyjmować postać pewnych wyrażeń, które, jeśli prawdziwe, będą wskazywać tylko na wybrane elementy w dokumencie. Wówczas własności zdefiniowane za selektorem odnosić się będą tylko do niektórych elementów, nie będą natomiast modyfikować innych.

Superflua non nocent

Są różne rodzaje selektorów. Specyfikacja CSS2 wyróżnia ich sporo, lecz nie wszystkie działają w przeglądarkach – nawet tych najnowszych (pisanie w roku 1999 – przypis autora). Dlatego, aby wyobrazić ich działanie, posługuję się obrazami, a nie prawdziwymi ilustracjami w przeglądarkach (obecnie wykorzystuję ilustracje w HTML – przypis autora).

Selektor uniwersalny (universal selector). Hej, komputerowcy – znacie tę komendę: dir *.txt? W DOS-ie tak tworzyło się listę wszystkich w danym katalogu plików o rozszerzeniu txt. Z selektorem uniwersalnym jest podobnie – piszemy:

*.marg { margin-left: 15% }

i już możemy to odczytać następująco: klasa 'marg’ (że to jest klasa użyta jako atrybut jakiegoś elementu języka HTML świadczy kropka po gwiazdce – patrz niżej) będzie nadawać każdemu opatrzonemu nią elementowi taką własność, że zostanie on wyświetlony z lewym marginesem równym 15% szerokości elementu nadrzędnego. Jeśli założymy, że szerokość głównego bloku BODY określona jest przez wielkość okna przeglądarki, że okno jest zmaksymalizowane i że rozdzielczość monitora akurat w danym wypadku to 800/600px, to akapit, będący dzieckiem BODY i ujęty w znacznik:

<P class="marg">To jest przykładowy akapit.</P>

będzie posiadał margines równy 15% z 800 pikseli, czyli 120 pikseli. Styl ten można przypisać do elementu DIV (DIV będzie rodzicem), w jego zasięgu umieścić wszystkie pozostałe składniki strony (dzieci i potomków) i proszę – mamy stroniczkę z marginesem:

<DIV class="marg">
  <P>To jest przykładowy akapit.</P>
  <UL>
   <LI>To jest przykładowa lista.</LI>
   <LI>To jest przykładowa lista.</LI>
  </UL>
  <A href="demo.html">To jest przykładowy odnośnik.<A>
</DIV>

Praktyka pozwala pominąć znak gwiazdki, wystarczy więc następujący zapis:

.marg { margin-left: 15% }

Selektor rodzajowy (type selector). Tutaj sprawa jest prosta. Selektor rodzajowy odnosi swoje działanie do tego elementu języka opisu strony, jaki zostanie wymieniony w definicji.

CODE { font-family : monospace; color: Green }
OL, UL, LI, DL, DT, DD  {
    font-family : Arial, Helvetica, sans-serif;
    font-size : 12px;
    /* Gdy kilka selektorów dzieli tę
       samą własność, można je zapisać
       łącznie, oddzielając przecinkami
    */
}

– co dla pierwszej definicji oznacza: każdy fragment tekstu objęty znacznikiem CODE będzie wyświetlony z użyciem czcionki monotypicznej (o stałej szerokości) w kolorze zielonym.

Selektor potomny (descendant selector). Jeśli chcemy, aby selektor wskazywał tylko na elementy, które są potomkami jakiegoś innego elementu, wówczas zapiszemy to tak:

<HTML>
 <HEAD>
 <TITLE>Selektor potomny 1</TITLE>
 <STYLE type="text/css">
  P {color : green}        /* selektor nr 1 */
  H3 {color : #FF33FF}     /* selektor nr 2 */
  H3 EM {color : blue}     /* selektor potomny nr 3 */
  EM {color : red}         /* selektor nr 4 */
  .bordo {color : #CC0000} /* selektor nr 5 */
 </STYLE>
 </HEAD>
 <BODY>
  <P>Tekst akapitu jest zielony (selektor 1).
  <EM>Tekst wyróżniony jest czerwony (selektor 4),
      mimo, że EM jest dzieckiem P.</EM></P>
  <H3>Nagłówek H3 jest różowy (selektor nr 2), jego
      dziecko <CODE>CODE</CODE> dziedziczy różowość.</H3>
  <H3 class="bordo">Ten nagłówek jest bordowy (selektor 5),
     <EM>ale tekst wyróżniony jest niebieski, bo w tym
        przypadku EM jest potomkiem H3, więc do niego
        odnosi się selektor 3.</EM>
     <CODE>Inny potomek H3 będzie nadal bordowy.</CODE>
  </H3>
 </BODY>
</HTML>

W przeglądarce zobaczymy:

Podobny przykład, ale tym razem selektor wskazuje na te elementy, które są „wnukami” elementu nadrzędnego. Konstrukcja wymaga odstępów między elementami i gwiazdką: A * B:

<HTML>
 <HEAD>
 <TITLE>Selektor potomny 2</TITLE>
 <STYLE type="text/css">
  DIV { background-color: #CCFFCC }  /* selektor nr 1 */
  P {color : Green }                 /* selektor nr 2 */
  .bordo { color : #CC0000 }         /* selektor nr 3 */
  DIV * P { color: #33CCFF }         /* selektor nr 4 */
 </STYLE>
 </HEAD>
<BODY>
 <DIV><!-- To jest "dziadek" (s. 1) -->
  <P>Paragraf zielony - "pierwsze dziecko" (s. 2)</P>
  <DIV class="bordo">"Drugie dziecko" jest bordowe (s. 3), ale
   <P>syn "drugiego dziecka" jest niebieski, bo to wnuczek (s. 4),
   </P> a to bordowa reszta drugiego dziecka.
  </DIV>
 </DIV>
</BODY>
</HTML>

W przeglądarce zobaczymy:

Selektor typu „dziecko” (child selector). Taki selektor będzie się odnosił jedynie do dzieci określonego elementu.

<html>
 <head>
 <title>Selektor "dziecko"</title>
 <style type="text/css">
  DIV { color : Red }        /* selektor nr 1 */
  EM  { font-style: italic } /* selektor nr 2 */
  P > SPAN { color: Blue }   /* selektor nr 3 */
 </style>
 </head>
<body style="background-color: #FFFFFF">
<div>Tekst w bloku jest czerwony
<em>i "wyróżnione" znacznikiem &lt;em&gt; dziecko
jest czerwone.</em>
<p>Również początek akapitu jest czerwony,
<span>ale jego dziecko jest niebieskie</span>.
<strong>Inne jego dziecko nie ma tego szczęścia</strong>.
</p>
<div><span>Kolejny tekst objęty znacznikiem &lt;span&gt; nie będzie
     niebieski, bo tutaj nie jest dzieckiem P.</span>
</div>
</div>
</body>
</html>

W przeglądarce ujrzymy:

Selektor „sąsiedni” (adjacent sibling selector). Tłumaczenie nieszczęśliwe, wiem, ale trzeba by użyć formuły „równorzędny selektor sąsiedni”, więc jeszcze śmieszniej. W istocie chodzi o wyróżnienie stylem takiego elementu A, który wraz innym B posiada tego samego rodzica i na dodatek umieszczony jest zaraz po B.

<HTML>
 <HEAD>
 <TITLE>Selektor sąsiedni</TITLE>
 <STYLE type="text/css">
   H1 + P { text-indent : 20px; } /* selektor sąsiedni */
 </STYLE>
 </HEAD>

<BODY style="background-color: #FFFFCC">
 <H1>Nagłówek</H1>
 <P>Akapit sąsiedni jest wysunięty.</P>
 <P>Akapit, który nie jest sąsiadem,
    nie jest wysunięty.</P>
</BODY>
</HTML>

W przeglądarce ujrzymy:

Selektor atrybutu (attribute selector). Selektory tego rodzaju będą oznaczać tylko elementy opatrzone konkretnym atrybutem i/lub atrybutem posiadającym określoną wartość. Wyobraźmy sobie, że na stronie znajduje się mieszanina tekstu polskiego i angielskiego; opatrując właściwe akapity atrybutem 'lang’ możemy sterować wyświetleniem bądź to tekstu angielskiego bądź polskiego. Prosty przykład:

 <html>
 <head>
  <title>Selektor atrybutu</title>
  <style type="text/css">
   H1[title] { color : Blue; cursor: help } /* selektor atrybutu */
   *[lang|="en"] { color : green }
   *[lang|="pl"] { color : red }
  </style>
 </head>
<body>
 <h1 title="To jest nagłówek wyróżniony atrybutem">
     Nagłówek niebieski</h1>
 <h1>Nagłówek standardowy</h1>
 <p lang="pl">Akapit w języku polskim.</p>
 <p lang="en">A paragraph in English.</p>
</body>
</html>

I rezultat:

Selektory atrybutywne mają dość urozmaiconą składnię. Z powyższego przykładu wywnioskować można, że selektor ten używa kwadratowych nawiasów ELEMENT [atrybut]. A oto inne warianty tego selektora:

[atrybut=wartość]
Oznacza tylko elementy opatrzone konkretnym atrybutem, np. atrybutem width posiadającym określoną wartość 200px.
[atrybut~=wartość]
Oznacza elementy opatrzone większą liczbą atrybutów, a między innymi jakimś atrybutem, np. class posiadającym np. wartość "demo". W języku HTML najprościej jest pisać w definicji stylu .demo, to znaczy stosować selektor typu klasyfikator, a w dokumencie HTML wywoływać styl poprzez użycie konstrukcji <ELEMENT>.
[atrybut|=wartość]

Oznacza elementy, w których atrybut jest listą słów połączonych łącznikiem, z których najważniejsze jest to pierwsze. Np. selektor P[lang|=”fr”] wyróżni akapit <P lang="fr-FR"> (francuski „francuski”) oraz <P lang="fr-BE"> (francuski „belgijski”).

In vili veste nemo tractat honeste – albo raczej odwrotnie

Wiadomo już, że jeśli któryś element języka opisu strony opatrzymy dowolnym zestawem własności, to fragmenty tekstu objęte danym znacznikiem będą wyświetlane na stronie zgodnie z tymi własnościami. W praktyce często opatrujemy takimi domyślnymi własnościami elementy najczęściej używane, np. P. Myślę tu oczywiście o przypadku, gdy arkusz stylów odnosi się do jednej lub więcej niż jednej strony. Wówczas wszystkie akapity będą wszędzie jednakowo sformatowane. Ale jest sposób na to, aby „uwolnić” elementy od sztywno zdefiniowanego zestawu własności.

Selektor typu „klasyfikator” (class selector). Składnia arkuszy stylów pozwala zastosować jako selektor tzw. klasyfikator. Klasyfikator wskazujemy przez użycie kropki. Jest to równoważne konstrukcji [atrybut~=wartość], więc definicja:

DIV.tlo { background-color : #FFFFCC }

jest identyczna z

DIV[class~=tlo] { background-color : #FFFFCC }

co się czyta następująco: każdy blok objęty znacznikiem <DIV> i opatrzony atrybutem class="tlo", będzie miał tło w kolorze #FFFFCC.

Selektor typu „identyfikator” (ID selector). W języku HTML atrybut ID jednoznacznie wskazuje dany element przez nadanie mu niepowtarzalnego w danym dokumencie identyfikatora, np. <P ID=pierwszy>. W tym samym dokumencie HTML inny element nie może już posiadać wartości ID=pierwszy. W CSS selektor typu „identyfikator” oznaczany jest znakiem „#”. W poniższym przykładzie:

#tytul1 { text-align: center }

identyfikator wskazuje element H1, którego atrybut ID ma wartość "tytul1". Tylko jeden nagłówek (tytuł stopnia pierwszego) oznaczony tym identyfikatorem będzie wyśrodkowany:

<H1 ID=tytul1>Tytuł wyśrodkowany</H1>
<H2>Tytuł niewyśrodkowany</H2>

Identyfikatory w zasadzie działają tak samo jak klasyfikatory, z jedną różnicą: o ile selektor „klasowy” może się odnosić do szerokiej grupy elementów, które będą podzielać wspólne własności, o tyle identyfikator w istocie wyróżnia dany element, wskazuje na niego, zatem nie można jednym i tym samym identyfikatorem opatrywać kilku znaczników w dokumencie. Identyfikatory są pożyteczne wszędzie tam, gdzie stosowany jest dynamiczny HTML i dynamiczne style. Np. można zaplanować zmianę koloru napisów lub tła jako reakcję na zdarzenie (kliknięcie lub przesunięcie myszy).

Przedstawione w tej części rodzaje selektorów można zestawiać w bardziej skomplikowane kombinacje, które precyzyjnie pozwalają „aplikować” styl do określonych elementów, np.:

DIV > P[lang="pl"] {
font-family : "Arial CE", Arial, Helvetica, sans-serif;
}
DIV > P[lang|="en"] {
font-family : Arial, Helvetica, sans-serif;
}

W praktyce, ze względu na fakt, że przeglądarki akceptują tylko niektóre z przedstawionych wyrażeń, niezawodnym sposobem formatowania treści jest posłużenie się klasyfikatorami oraz identyfikatorami w definicjach stylów oraz atrybutami class oraz ID w stosowanych w dokumencie elementach języka HTML.

Powinienem w tym miejscu przedstawić tzw. pseudoklasy i pseudoelementy, gdyż wiąże się to z konstrukcją selektorów w definicji stylu. Nie myślcie jednak, że nie żywię żadnych ludzkich uczuć, więc tym razem dam już spokój. O pseudoklasach i pseudoelementach napiszę, gdy zdaży się pseudookazja.

Podsumowanie

Z tego co wcześniej napisano o selektorze uniwersalnym wynika, że selektor – klasyfikator jest wszechstronnym i elastycznym instrumentem, za którego pomocą można wpływać na własności dowolnego elementu w dokumencie HTML. Specyfikacja HTML 4.01 wręcz zachęca do rezygnowania z wielu tradycyjnych atrybutów, niektóre z nich nawet odrzuca, określając je mianem „deprecated” (niezalecane), a w zamian proponuje stosowanie odpowiednio zdefiniowanych za pomocą CSS klas. Także moje doświadczenia pozwalają mi stwierdzić, że stosowanie selektorów „klasowych” jest bardzo wygodne i efektywne. Amen.

Scroll to Top