Kategorie
CSS

Selektory CSS 3

Tłumaczenie artykułu Rogera Johanssona na temat selektorów CSS 3.

We wrześniu i październiku 2005 roku opublikowałem serię artykułów na temat selektorów CSS 2.1. Podsumowując, większość z opisanych tam selektorów można używać dziś w nowoczesnych przeglądarkach jak Mozilla/Firefox, Safari i Opera. Potrzebujemy jeszcze poczekać, aż Internet Expolorer zacznie równać do najlepszych. Deklaracja pełnego wsparcia dla selektorów CSS 2.1 w Internet Explorer 7 to dobra wiadomość.

Jeśli popatrzymy w przyszłość to specyfikacja CSS 3 oferuje wiele nowych i potężnych selektorów. Wiele z nich zostało już zaimplementowanych w nowoczesnych przeglądarkach. Niestety ich obsługa póki co jest dość niejednolita i programiści nie mogą do końca na nich polegać. W niektórych przypadkach stosowanie selektorów CSS 3 jest zasadne, więc warto przyjrzeć się im bliżej.

W tym artykule, odnoszę się do specyfikacji przedstawionej w Selectors W3C Working Draft 15 December 2005. Nowe selektory opisane w tym dokumencie będą używane przez CSS 3, ale także inne języki programowania. Kiedy czytasz ten artykuł po miesiącach, albo nawet latach, może warto sprawdzić czy nie jest dostępna aktualniejsza wersja.

Nie zamierzam tu opisywać podstaw na temat selektorów CSS. Jeśli potrzebujesz przypomnienia wiadomości to dobrym miejscem na początek jest artykuł Selektory CSS 21 – część 1.

Na początku poznajmy nowe selektory CSS 3:

Przegląd selektorów CSS 3
Selektor Wzorzec Opis
Atrybut E[att^=”val”] Pasuje do dowolnego elementu E, którego atrybut att rozpoczyna się od wartości “val”.
Atrybut E[att$=”val”] Pasuje do dowolnego elementu E, którego atrybut att kończy się wartością “val”.
Atrybut E[att*=”val”] Pasuje do dowolnego elementu E, którego atrybut att zawiera wartość “val”.
Pseudo-klasa E:root Pasuje do korzenia dokumentu. W przypadku HTML, korzeniem jest zawsze element HTML.
Pseudo-klasa E:nth-child(n) Pasuje do dowolnego elementu E, który jest n-tym dzieckiem swojego rodzica.
Pseudo-klasa E:nth-last-child(n) Pasuje do dowolnego elementu E, który jest n-tym dzieckiem swojego rodzica, licząc od ostatniego dziecka.
Pseudo-klasa E:nth-of-type(n) Pasuje do dowolnego elementu E, który jest n-tym rodzeństwem swojego typu.
Pseudo-klasa E:nth-last-of-type(n) Pasuje do dowolnego elementu E, który jest n-tym rodzeństwem swojego typu, licząc od ostatniego rodzeństwa.
Pseudo-klasa E:last-child Pasuje do dowolnego elementu E, który jest ostatnim dzieckiem swojego rodzica.
Pseudo-klasa E:first-of-type Pasuje do dowolnego elementu E, który pierwszym rodzeństwem swojego typu.
Pseudo-klasa E:last-of-type Pasuje do dowolnego elementu E, który ostatnim rodzeństwem swojego typu.
Pseudo-klasa E:only-child Pasuje do dowolnego elementu E, który jest jedynym dzieckiem swojego rodzica.
Pseudo-klasa E:only-of-type Pasuje do dowolnego elementu E, który jest jedynym rodzeństwem swojego typu.
Pseudo-klasa E:empty Pasuje do dowolnego elementu E, który nie ma dzieci, w tym także węzłów tekstu.
Pseudo-klasa E:target Pasuje do elementu E, który jest celem danego adresu URL.
Pseudo-klasa E:enabled Pasuje do dowolnego elementu E interfejsu użytkownika (kontrola formularza), który jest dostępny.
Pseudo-klasa E:disabled Pasuje do dowolnego elementu E interfejsu użytkownika (kontrola formularza), który jest niedostępny.
Pseudo-klasa E:checked Pasuje do dowolnego elementu E interfejsu użytkownika (kontrola formularza), który jest zaznaczony.
Pseudo-klasa E::selection Pasuje do dowolnego elementu E interfejsu użytkownika (kontrola formularza), który jest wybrany lub wyróżniony przez użytkownika.
Pseudo-klasa E:not(s) Pasuje do dowolnego elementu E, który nie pasuje do selektora prostego s.
Ogólne rodzeństwo E ~ F Pasuje do dowolnego elementu F, który jest poprzedzony elementem E.

Nie martw się, jeśli coś nie jest do końca jasne. Każdy selektor zostanie w artykule dokładnie omówiony, również z przykładami użycia.

Selektory dopasowania ciągu znaków

Grupa ta jest nowa, a selektory w niej zawarte pozwalają programistom znaleźć elementy na podstawie części wartości atrybutu.

Przyjmijmy, że mamy dokument HTML o następującej strukturze:

<div id="nav-primary"></div>
<div id="content-primary"></div>
<div id="content-secondary"></div>
<div id="tertiary-content"></div>
<div id="nav-secondary"></div>

Poprzez użycie selektorów dopasowania możesz odnieść się do strukturalnych części dokumentu.

Następująca reguła ustawia kolor tła dla wszystkich elementów div, których id rozpoczyna się od “nav”:

div[id^="nav"] { background:#ff0; }

W tym wypadku selektor będzie pasował do div#nav-primary i div#nav-secondary.

Aby znaleźć elementy div, których id kończy się ciągiem “primary”, możesz użyć następującej reguły:

div[id$="primary"] { background:#ff0; }

Tym razem selektor będzie pasował do div#nav-primary i div#content-primary.

Następujące reguły stosują się do wszystkich elementów div, których id zawiera ciąg “content”:

div[id*="content"] { background:#ff0; }

Elementy, których dotyczy to reguła to div#content-primary, div#content-secondary i div#tertiary-content.

Selektory dopasowania ciągu znaków są w pełni wspierane przez ostatnie wersje przeglądarek: Mozilla, Firefox, Flock, Camino, Safari, OmniWeb i Opera, więc gdyby pominąć Internet Explorer moglibyśmy już zacząć ich używanie.

Pseudo-klasa :target

Adresy URL z względnym odnośnikiem to takie, które zawierają “#” i linkują na podstawie nazwy lub identyfikatora elementu w obrębie dokumentu. Stylizacja takiego elementu jest możliwa dzięki pseudo-klasie :target. Jeśli aktualny adres URL nie zawiera fragmentu z identyfikatorem to pseudo-klasa :target nie pasuje do żadnego elementu.

W przypadku wspomnianej wcześniej struktury HTML, następująca zasada tworzy kontur wokół elementu div#content-primary kiedy adres URL będzie zawierał identyfikator:

div#content-primary:target { outline:1px solid #300; }

Przykład takiego URL to http://www.example.com/index.html#content-primary.

Pseudo-klasa :target jest obecnie wspierana przez przeglądarki rodziny Mozilla i Safari.

Pseudo-klasy interfejsu użytkownika

Pseudo-klasa :enabled i :disabled

Pseudo-klasy:enabled i :disabled pozwalają programistom na określenie wyglądu elementów formularzy, które są dostępne lub niedostępne, pomimo tego, że przeglądarka sama stylizuje kontrolki formularzy. Poniższe reguły zmieniają kolory tła dla pól tekstowych w formularzu w zależności czy są one dostępne czy niedostępne:

input[type="text"]:enabled { background:#ffc; }

input[type="text"]:disabled { background:#ddd; }

Pseudo-klasa :checked

Pseudo-klasa :checked pozwala programistom na określenie wyglądu wybranych (aktywnych) kontrolek radio i checkbox w formularzach. Również w tym przypadku przeglądarka umożliwia stylizowanie elementów formularzy. Poniższe reguły CSS tworzą zieloną ramkę wokół wybranych (aktywnych) elementów radio i checkbox:

input:checked { border:1px solid #090; }

Opera oraz przeglądarki z rodziny Mozilla obsługują pseudo-klasy interfejsu użytkownika.

Należy zaznaczyć, że wygląd formularzy w przeglądarkach może się bardzo różnić, a same przeglądarki bardzo restrykcyjnie traktują zmiany kontrolek formularzy przez programistów. Więcej na ten temat możesz dowiedzieć się z artykułu Styling form controls i Styling even more form controls.

Strukturalne pseudo-klasy

Strukturalne pseudo-klasy pozwalają programistom odwołać się do elementów ze struktury dokumentu, do których dostęp poprzez selektory proste i złożone jest niemożliwy. Strukturalne pseudo-klasy są bardzo potężne, ale niestety nie wszystkie z nich są wspierane przez nowoczesne przeglądarki.

Pseudo-klasa :root

Pseudo-klasa :root odnosi się do do elementu korzenia dokumentu. Dla dokumentów HTML takim korzeniem jest zawsze element HTML, w takim razie poniższe reguły są takie same. Nie do końca, ponieważ :root ma większe znaczenie niż html):

:root { background:#ff0; }
html { background:#ff0; }

Pseudo-klasa :root jest aktualnie wspierana przez przeglądarki z rodziny Mozilla i Safari.

Pseudo-klasa :nth-child()

Pseudo-klasa :nth-child() odnosi się do elementu, który ma przed sobą określoną liczbę rodzeństwa w drzewie dokumentu. Wartość, która o tym decyduje, znajduje się w nawiasach i może być liczą, słowem kluczowym lub formułą.

Numer b pasuje do b-tego dziecka. Następująca reguła stosuje się do wszystkich elementów p, które są trzecim dzieckiem swojego rodzica:

p:nth-child(3) { color:#f00; }

Słowa kluczowe odd i even można wykorzystać do elementów o indeksach nieparzystych i parzystych. Indeks pierwszego elementu to 1, więc ta reguła będzie pasować do każdego paragrafu, który jest pierwszym, trzecim, piątym i kolejnym dzieckiem swojego rodzica:

p:nth-child(odd) { color:#f00; }

Poniższa reguła pasuje do elementów p, które są drugim, czwartym, szóstym i kolejnym dzieckiem swojego rodzica.:

p:nth-child(even) { color:#f00; }

Formuła an + b może być użyta do stworzenia bardziej złożonych wzorów. W przykładowym wzorze, a reprezentuje ilość cykli, n to licznik, startujący od zera, a b przesunięcie wartości. Wszystkie wartości są liczbami całkowitymi. Aby wszystko dokładnie zrozumieć, zapoznaj się z poniższymi przykładami.

Poniższe reguły będą pasować do wszystkich elementów p, których indeks dzieli się przez 3. W pierwszej regule zero można pominąć, tak jak to zrobiliśmy zostało zapisane w drugiej regule:

p:nth-child(3n+0) { color:#f00; }
p:nth-child(3n) { color:#f00; }

Przesunięcie wartości służy do określenia momentu, w którym reguła zaczyna obowiązywać. Jeżeli mamy tabelę z 20 wierszami i chcemy zmienić kolor tła nieparzystych wierszy, ale dopiero od dziesiątego to stosujemy daną regułę:

tr:nth-child(2n+11) { background:#ff0; }

Dopóki n rozpoczyna się od 0, pierwszy element tr, przy którym reguła będzie się stosować to jedenasty element. Następnie będzie trzynasty, piętnasty i tak dalej.

Więcej szczegółów można znaleźć w sekcji :nth-child() pseudo-class specyfikacji selektorów CSS3.

A jak wygląda wsparcie przeglądarek dla tych bardzo użytecznych selektorów? Z tego co wiem, to żadna z nich nie obsługuje w pełni, tych selektorów. Popraw mnie jeśli się mylę.

Pseudo-klasa :nth-last-child()

Pseudo-klasa :nth-last-child() działa tak samo jak pseudo-klasa :nth-child(), z tym wyjątkiem, że odnosi się do inaczej liczonego elementu w strukturze dokumentu. Inaczej mówiąc, rozpoczynamy liczenie od ostatniego dziecka, a nie pierwszego i liczymy wstecz. Poniższa reguła będzie pasowała do przedostatniego elementu tr tabeli:

tr:nth-last-child(2) { background:#ff0; }

Pseudo-klasa :nth-last-child() nie jest wspierana przez żadną przeglądarkę.

Pseudo-klasa :nth-of-type()

Pseudo-klasa :nth-of-type() działa dokładnie jak pseudo-klasa :nth-child(), ale reguły odnoszą się tylko do elementów tego samego typu. Taka reguła pasuje do takich elementów p, które są trzecim elementem p swojego rodzica:

p:nth-of-type(3) { background:#ff0; }

Ten selektor jest użyteczny, kiedy chcemy być pewni, że rzeczywiście odnosimy się do trzeciego elementu p. Na początku można było dojść do wniosku, że odpowiada za to pseudo-klasa nth-child, ale :nth-child(3) obejmuje wszystkie elementy rodzeństwa, więc rezultat będzie inny chyba, że wszystkie elementy p mają jako rodzeństwo tylko i wyłącznie elementy p.

Pseudo-klasa :nth-of-type() nie jest obecnie wspierana przez żadne przeglądarki.

Pseudo-klasa :nth-last-of-type()

Pseudo-klasa :nth-last-of-type() dotyczy elementu, który ma określony number spośród rodzeństwa danego typu w strukturze dokumentu. Pseudo-klasa :nth-last-child() rozpoczyna liczenie od końca, a nie od początku oraz liczy elementy wstecz. Następująca reguła pasuje do każdego drugiego od końca rodzeństwa dla p:

p:nth-last-of-type(2) { background:#ff0; }

Pseudo-klasa :nth-last-of-type() nie jest obecnie wspierana przez przeglądarki.

Pseudo-klasa :last-child

Pseudo-klasa :last-child odnosi się do elementu. który jest ostatnim dzieckiem swojego rodzica. To dokładnie to samo co :nth-last-child(1). Reguła ta pasuje do wszystkich elementów p, które są ostatnim dzieckiem elementu swojego rodzica:

p:last-child { background:#ff0; }

Pseudo-klasa :last-child działa w przeglądarkach z rodziny Mozilla. Opera nie wspiera jej wcale, a Safari tylko w częściowy sposób. O dziwo, działa to jak powinno w OmniWeb (wersja 5.1.1), pomimo faktu powiązania z Safari. Może to być spowodowane uwstecznieniem ostatniej wersji Apple WebKit, ponieważ OmniWeb korzysta przeważnie ze starszych wersji WebKit w porównaniu z Safari.

Pseudo-klasa :first-of-type

Pseudo-klasa :first-of-type obejmuje element, który jest pierwszym spośród rodzeństwa swojego typu. Działa dokładanie jak :nth-of-type(1).

p:first-of-type { background:#ff0; }

Pseudo-klasa :first-of-type nie jest obecnie wspierana przez przeglądarki.

Pseudo-klasa :last-of-type

Pseudo-klasa :last-of-type obejmuje element, który jest ostatnim spośród rodzeństwa swojego typu. Działa dokładanie jak :nth-last-of-type(1).

p:last-of-type { background:#ff0; }

Pseudo-klasa :last-of-type nie jest obecnie wspierana przez przeglądarki.

Pseudo-klasa :only-child

Pseudo-klasa :only-child odnosi się do elementu, którego rodzic nie ma innych dzieci. To samo :first-child:last-child lub :nth-child(1):nth-last-child(1), ale z niższym priorytetem.

p:only-child { background:#ff0; }

Pseudo-klasa :only-child działa w przeglądarkach Mozilli. Safari zdaje się interpretować to jako :first-child, czyli powyższa reguła pasuje do wszystkich elementów p w dokumencie, które są pierwszym dzieckiem swojego rodzica.

Pseudo-klasa :only-of-type

Pseudo-klasa :only-of-type obejmuje swoim działaniem element, którego rodzic nie ma więcej dzieci danego typu. Działa tak samo, ale z mniejszym priorytetem jak :first-of-type:last-of-type lub :nth-of-type(1):nth-last-of-type(1).

p:only-of-type { background:#ff0; }

Pseudo-klasa :only-of-type nie jest aktualnie wspierana przez przeglądarki.

Pseudo-klasa :empty

Pseudo-klasa :empty odnosi się do elementu, który nie ma dzieci. Wliczamy do tego, także węzły tekstowe, więc w następującym przypadku, tylko pierwszy element jest pusty:

<p></p>
<p>Text</p>
<p><em></em></p>

Następujące reguły CSS będą pasować do pierwszego elementu:

p:empty { background:#ff0; }

Pseudo-klasa :empty jest obecnie wspierana przez przeglądarki z rodziny Mozill. Safari błędnie stosuje te reguły do wszystkich elementów danego typu.

Pseudo-klasa negacji

Pseudo-klasa negacji, zapisana jako :not(s), bierze prosty selektor s jako argument. Swoim zasięgiem obejmuje elementy, które nie są objęte działaniem selektora prostego. Przykładowo, następujące reguły CSS stosują się do wszystkich elementów, które nie są elementem p:

:not(p) { border:1px solid #ccc; }

Pseudo-klasa negacji działa aktualnie w przeglądarkach Mozilli i Safari.

Pseudo-element ::selection

Pseudo-element ::selection pasuje do części elementu, który jest aktualnie wybrany lub wyróżniony przez użytkownika. Jedyna możliwość użycia tego selektora to zmiana wyglądu wybranego tekstu.

Tylko kilka właściwości CSS można stosować dla pseudo-klasy ::selection: color, background, cursor, and outline.

Następująca reguła uczyni zaznaczony tekst czerwonym:

::selection { color:#f00;	}

Pseudo-element ::selection działa obecnie tylko w przeglądarkach Safari. Implementacja tego selektora w Safari jest trochę nieprzewidywalna. Mozilla, póki co wspiera własne rozszerzenia ::-moz-selection, a prefiks zostanie w przyszłości usunięty.

Selektor ogólnego rodzeństwa

Selektor ogólnego rodzeństwa składa się z dwóch selektorów prostych rozdzielonych znakiem “tyldy” (~). Pasuje do tych tych elementów drugiego selektora prostego, które są poprzedzone elementem pierwszego selektora. Oba elementy muszą mieć tego samego rodzica, ale drugi element nie musi być bezpośrednio poprzedzony pierwszym elementem. Podana reguła CSS obejmuje elementy ul, które są poprzedzone elementem p i mają tego samego rodzica:

p ~ ul { background:#ff0; }

Opera i przeglądarki rodziny Mozilla obsługują selektor ogólnego rodzeństwa.

Niezbędne wsparcie po stronie przeglądarek

Niektóre selektory CSS 3 są lepiej wspierane, a inne gorzej. Niestety, ale kilka najbardziej użytecznych selektorów nie jest wspieranych w ogóle. Wszystko to sprawia, że w obecnym czasie wykorzystanie selektorów przedstawionych w artykule jest trudne. Pozostaje jedynie czekanie na moment pełnego wsparcia selektorów CSS 3 przez przeglądarki, a póki co korzystanie z już obsługiwanych.

Więc, która przeglądarka twoim zdaniem jako pierwsza będzie wspierała większość lub wszystkie selektory CSS 3? Safari, Firefox czy Opera? A może nawet Internet Explorer?

Ten artykuł jest tłumaczeniem oryginalnego tekstu CSS 3 selectors explained, którego autorem jest Roger Johansson.

8 odpowiedzi na “Selektory CSS 3”

Z tego co właśnie widzę u siebie na komputerze wynika, że pseudoklasa :nth-child() działa poprawnie w nowych wersjach Opery, Safari, Firefoksa i Chroma. Oczywiście nie działa w IE.

Poza tym wzór formuły an + b według mnie działa odwrotnie: an to skok (np 2n to co drugi wiersz) natomiast + b to miejsce o którego ma zacząć (np. +5 to start od 5 wiersza tabeli) działać dany styl.

A może źle zrozumiałem co autor miał na myśli ;)

Z tego co właśnie widzę u siebie na komputerze wynika, że pseudoklasa :nth-child() działa poprawnie w nowych wersjach Opery, Safari, Firefoksa i Chroma. Oczywiście nie działa w IE.

hmm zniknął fragment z html, więc wpiszę go inaczej:

(li o klasie „lista1”)(a)(koniec li) (li o klasie „lista1 wybrane”(a)(koniec li)

(li o klasie „lista2”)(a)(koniec li) (li o klasie „lista2 wybrane”(a)(koniec li)

Jeśli chcesz się odnieść do elementu <a> w elemencie <li>, który ma klasy .lista1 oraz .wybrane wystarczy użyć prostego selektora kontekstu czyli li.lista1.wybrane a

Możliwość komentowania została wyłączona.