Kaskadowe arkusze stylów dają najwięcej możliwości projektantom stron WWW. Dzięki CSS możemy całkowicie odmienić wygląd strony w kilka minut, bez ingerencji w kod HTML. Ale mimo ogromnego potencjału CSS, najczęściej nie korzystamy z możliwości jego pseudoklas, pseudoelementów oraz specjalnych znaczników i nadmiernie komplikujemy dokument HTML ogromną ilością niepotrzebnych klas, identyfikatorów, DIV-ów oraz SPAN-ów. Najlepszym sposobem, aby Twój HTML nie zawierał nadmiaru niepotrzebnych tworów jest używanie bardziej złożonych selektorów CSS. Dzięki temu kod będzie bardziej czytelny a arkusze CSS mniej skomplikowane.
Specyficzność CSS (z ang. ‘specifity’) określa wagę właściwości CSS. Innymi słowy, jeśli w dwóch lub więcej miejscach zostaną zadeklarowane dla tego samego elementu różne właściwości, np. różne kolory tła, specyficzność określa, która z deklaracji jest „ważniejsza”.
Ważna jest więc umiejętność obliczania specyficzności danego elementu, która pozwala niekiedy zaoszczędzić sporo czasu straconego na przeszukiwaniu pliku CSS w odpowiedzi na pytanie: „dlaczego ten akapit ma niebieskie tło, skoro deklarowałem zielone”.
Oto jak oblicza się specyficzność konkretnego selektora:
| <span style=”color:red”>Czerwony tekst</span> |
| #sidebar, #footer { color:red; } |
| .form { margin-top:20px; } |
| img { border:none; } |
Jeśli właściwość danego elementu będzie różnie zadeklarowana w wielu miejscach, dominującą będzie ta, która ma największą specyficzność (nawet, gdy jest zadeklarowana wcześniej niż pozostałe).
Przykłady:
Spośród poniższych dwóch selektorów, właściwości tego pierwszego zostaną nadane elementom, ponieważ ma on większą specyficzność.
W zrozumieniu specyficzności pomóc może podstawowe narzędzie webmastera, czyli Firebug. Po zaznaczeniu elementu na karcie HTML, w oknie styl po prawej stronie można przeglądać, jakie właściwości ma on nadany w kolejności od największej specyficzności.

Przydatne linki:
Selektory atrybutów pozwalają na odnoszenie się do elementów według wartości ich konkretnych atrybutów. Można więc skonstruować selektor, który będzie się odnosił do dowolnych elementów w Twoim HTML-u, pod warunkiem, że mają określoną (na przykład) klasę.
Istnieje sześć typów takich selektorów:
Na przykład, gdy chcesz zmienić kolor tła wszystkich elementów, których klasa zawiera “post”, użyj poniższego kodu:
| div[class*="post"] { background-color: #333; } |
Zastosowanie selektorów atrybutów ułatwia także dodawanie różnych ikon obok linków do plików różnych typów.
| a[href$=".jpg"] { background: url(jpeg.gif) no-repeat left 50%; padding: 2px 0 2px 20px; } a[href$=".pdf"] { background: url(pdf.gif) no-repeat left 50%; padding: 2px 0 2px 20px; } a[href$=".doc"] { background: url(word.gif) no-repeat left 50%; padding: 2px 0 2px 20px; } |
W powyższym przykładzie zastosowano selektory atrybutów – te odnoszą się do linków, których atrybuty href kończą się na .jpg, .pdf oraz .doc.
Selektory atrybutów są obsługiwane przez wszystkie nowe przeglądarki, oprócz nadal popularnego Internet Explorer 6. Jeśli w swoich CSS-ach stosujesz wyżej wspomniane selektory, pamiętaj, aby dla użytkowników IE6 zapewnić funkcjonalną wersję strony. Wersja dla IE6 nie musi być identyczna (jeśli tylko nie jest to wymagane) z tymi przeznaczonymi dla pozostałych przeglądarek – jeśli chcesz zastosować selektory atrybutów do mało ważnych elementów, które tylko „dodają uroku”, nie przejmuj się IE6 i zrób to.
Selektor dziecka (ang. child) jest reprezentowany symbolem “>”. Pozwala na odnoszenie się do elementu, który leży o jeden rząd niżej w hierarchii dokumentu.
Na przykład, jeśli chcesz nadać kolor czerwony wszystkim pogrubionym elementom, które znajdują się bezpośrednio w znacznikach <p>, ale nie leżą głębiej w hierarchii, użyj poniższego kodu:
| p > b { color:red; } |
Możesz także zastosować kombinację selektorów dziecka i potomka. Poniższy fragment arkusza CSS odnosi się do elementów pogrubionych (<b>), znajdujących się wewnątrz znacznika <div>, który jest dzieckiem <body>.
Brak znaku „>” w przykładowym kodzie nie jest błędem – oznacza, że znacznik <b> może znajdować się o więcej niż jeden rząd niżej w hierarchii dokumentu. (wewnątrz <div> można by umieścić akapit <p>, a dopiero wewnątrz niego tekst pogrubiony <b>, a poniższy selektor w dalszym ciągu by się do niego odnosił).
| body > div b { margin-left: 30px; } |
Podobnie jak w wypadku selektorów atrybutów, selektory dzieci nie są obsługiwane przez IE6. Jeśli efekt, który chcesz osiągnąć przez stosowanie selektorów dzieci, jest kluczowy dla witryny, rozważ wprowadzenie dodatkowych klas lub dodatkowego arkusza tylko dla IE.
Selektor braci, oznaczany znakiem plusa (+), służy do nadania stylu drugiemu z elementów, które są dzieckiem tego samego elementu, leżą na tym samym poziomie w hierarchii dokumentu i następują zaraz po sobie.
Przykład użycia: selektor braci jest bardzo przydatny, gdy na przykład chcesz wyróżnić pierwszy akapit po tytule (<h2>) w wielu artykułach. Zamiast edytować kilkadziesiąt plików wystarczy dodać prostą regułę do arkusza CSS.
| h2 + p { font-style:italic; } |
Jeśli chciałbyś się więc odnieść do wszystkich akapitów, które występują po elemencie <h1> wewnątrz DIV-a o klasie „post” zastosuj poniższy kod:
| div.post h1 ~ p { font-size: 13px; } |
Analogicznie do powyższych, selektory braci również nie są obsługiwane przez IE6. Nie warto jednak rezygnować z fajnych efektów, które można osiągnąć w większości przeglądarek dzięki nim, pozostawiając dla użytkowników IE6 tylko wersję „bez wodotrysków”.
Są również nazywane dynamicznymi pseudoklasami, ponieważ nie ma ich w HTML-u i istnieją tylko, gdy użytkownik wchodzi w interakcje ze stroną.
Istnieją dwa typu pseudokras – te związane z łączami (:link oraz :visited) oraz te z akcjami wykonywanymi przez użytkownika (:hover, :active oraz :focus). Ze wszystkich selektorów w tym artykule prawdopodobnie te powyższe są najczęściej używane.
Pseudoklasa :link odnosi się do łączy, które nie zostały jeszcze odwiedzone przez użytkownika, natomiast :visited, jak sama nazwa wskazuje – odnosi się do tych już klikniętych.
:hover odnosi się do elementów, nad którymi znajduje się obecnie kursor myszy, podczas gdy :active dotyczy tylko elementów, które są aktywne (np. użytkownik właśnie je klika myszą). Ostatnia z pseudoklas, :focus dotyczy elementów, które są aktywne – najczęściej stosuje się ją w formularzach, których pola zmieniają styl (tło, ramkę), gdy są aktywne.
Można stosować jednocześnie wiele pseudoklas razem. Dla przykładu możesz napisać styl dla elementu input, który będzie miał inny kolor tła i ramkę, podczas, gdy będzie aktywny i jeszcze inny, gdy będzie aktywny i dodatkowo kursor myszy znajdzie się ponad nim.
| input:focus { background: #D2D2D2; border: 1px solid #5E5E5E; } input:focus:hover { background: #C7C7C7; } |
Dynamiczne pseudoklasy są obsługiwane przez wszystkie przeglądarki, nawet przez IE6. Pamiętaj, że jednak w tej przeglądarce :hover odnosi się tylko do linków, a dopiero w IE8 możesz zastosować pseudoklasę :active do innych elementów niż łącza.
Pseudoklasa :first-child odnosi się do pierwszego dziecka dowolnego elementu. Jeśli na przykład chciałbyś dodać pierwszemu elementowi <li> z listy nienumerowanej dodatkowy margines, użyj poniższego kodu:
| ul > li:first-child { margin-top: 10px; } |
| #sidebar > h2 { margin-top: 10px; } #sidebar > h2:first-child { margin-top: 0; } |
IE6 nie obsługuje :first-child. W zależności od tego, do czego zastosujesz tę pseudoklasę, jej użycie może spowodować tylko niewielkie różnice w wyświetlaniu marginesów lub, jeśli za jej pomocą ustalisz cały layout, „rozsypać” cały układ strony. Uważaj na to!
Pozwala ona na odniesienie się do elementu, w zależności od jego języka. Przykładowo, można ustawić różne tła dla linków w przypadku różnych języków.
| :lang(en) > a#flag { background-image: url(english.gif); } :lang(fr) > a#flag { background-image: url(french.gif); } |
Powyższe selektory będą odnosiły się do linku o identyfikatorze flag, jeśli jego ustawiony język będzie równy „en”/”fr” lub też będzie zaczynał się od „en”/”fr”, a zaraz potem będzie następował myślnik (np. „en-EN”).
W przypadku poniższego kodu:
| <body lang=fr> <p>Je suis Français.</p> </body> |
Selektor [lang|=fr] będzie odnosił się tylko do <body> (ponieważ tylko ten znacznik ma taki atrybut), natomiast pseudoklasa :lang(fr) będzie odnosiła się zarówno do <body>, jak i do akapitu <p> (dziedziczy on język od <body>).
Pseudoklasa :lang() jest obsługiwana przez wszystkie nowe przeglądarki oraz IE 8.
Kiedy korzystasz z linków z identyfikatorami, (np. http://twoja_strona/jakisfolder/#spistresci), możesz nadać odpowiedni styl elementowi, do którego odnosi się identyfikator dzięki pseudokrasie :target.
Wyobraź sobie długą stronę z dużą ilością tekstu i kilkudziesięcioma nagłówkami <h2> oraz ich spisem treści u góry. Dobrym rozwiązaniem jest zaakcentowanie, na przykład przez nadanie żółtego tła, tego elementu <h2>, który został wybrany przez użytkownika.
| h2:target { background: yellow; } |
Wszystkie nowoczesne przeglądarki oprócz IE obsługują :target.
Niektóre elementy HTML, tak jak pola input lub textarea mogą być zablokowane (disabled) lub (pola radio, checkboxy) zaznaczone (checked). Do tych stanów mogą się odnosić nowe w CSS3 pseudoklasy :checked, :enabled i :disabled.
W pierwszym przykładzie nadamy zablokowanym polom input jasnoszare tło i ramkę, natomiast w drugim wyróżnimy zaznaczone checkboxy dodatkowym lewym marginesem.
| input:disabled { border:1px dotted #999; background:#F2F2F2; } input[type=”checkbox”]:checked { margin-left: 15px; } |
Oczywiście, jak zwykle wszystkie nowoczesne przeglądarki oprócz IE obsługują powyższe pseudoklasy. Nic nie stoi na przeszkodzie, aby wykorzystać je i dodatkowo wyróżnić niektóre elementy w większości przeglądarek.
Psuedoklasa :nth-child() pozwala na odniesienie się do jednego lub kilku konkretnych dzieci danego elementu.
Aby odnieść się do konkretnego dziecka, wystarczy podać jego numer:
| ul li:nth-child(3) { color: red; } |
To zmieni trzeci kolor tekstu trzeciego elementu <li> wewnątrz listy na czerwony. Uwaga, jeśli wewnątrz list <ul> znajdują się inne niż <li> elementy, są także liczone jako dzieci.
Możesz także odnieść się do konkretnych dzieci, korzystając z odpowiednich wyrażeń. Poniższe obejmie co trzecie dziecko, rozpoczynając od czwartego.
| ul li:nth-child(3n+4) { color: yellow; } |
Jeśli jednak chcesz zacząć od pierwszego elementu i wyróżniać co drugi, użyj prostszego wyrażenia:
| ul li:nth-child(2n) { color: yellow; } |
| ul li:nth-child(-n+4) { color: green; } |
Pseudoklasa :nth-child może przyjąć wartość “even” or “odd”, które są analogicznie do “2n” (co drugie dziecko) i “2n+1” (co drugie, zaczynając od pierwszego).
Pseudoklasa :nth-last-child działa podobnie jak :nth-child z tą różnicą, że elementy są zliczane od ostatniego.
Pamiętacie poniższy przykład użycia :nth-child?
| ul li:nth-child(-n+4) { color: green; } |
Po zmianie klasy na :nth-last-child, zliczanie rozpocznie się od końca i zielone będą tylko cztery ostatnie.
nth-of-type działa prawie tak samo jak :nth-child, z tą różnicą, że liczone są tylko element danego typu.
To bardzo przydatna pseudoklasa, gdy chcemy odnosić się tylko do danych elementów, np. akapitów, podczas, gdy mogą one być „poprzeplatane” innymi, np. listami numerowanymi lub cytatami (inne elementy będą ignorowane).
Możesz używać tych samych wartości co w pseudoklasie :nth-child.
| div#content > p:nth-of-type(even) { color: blue; } |
Zgadliście! :nth-last-of-type działa analogicznie do :nth-of-type, z tą różnicą, że zlicza elementy od końca.
| ul li:nth-last-of-type(-n+4) { color: green; } |
Możemy pójść jeszcze dalej i połączyć wiele różnych pseudoklas. Poniższy przykład nada właściwość float:left wszystkim elementom img wewnątrz DIV-a post, oprócz pierwszego i ostatniego.
| div#post img:nth-of-type(n+2):nth-last-of-type(n+2) { float: left; } |
Pseudoklasa :last-child działa podobnie do :first-child, z tą różnicą, że odnosi się do ostatniego dziecka danego elementu. Możemy więc usunąć dolny margines ostatniego akapitu tekstu.
| .post > p:last-child { margin-bottom: 0; } |
Dzięki tym pseudoklasom możemy odnosić się do elementów, które są odpowiednio pierwszym i ostatnim dzieckiem danego typu.
Przykładowo, możemy zmienić styl pierwszej linii pierwszego akapitu wewnątrz elementu DIV, nawet, gdy jego pierwszym dzieckiem jest tytuł <h2>.
| div.post > p:first-of-type:first-line { font-variant: small-caps; } |
Ta pseudoklasa reprezentuje element, który jest jedynym dzieckiem. Załóżmy, że na swojej stronie masz kilkadziesiąt elementów <div> z akapitami tekstu wewnątrz. Ale jeśli w danym DIV-ie akapit jest tylko jeden, można zwiększyć jego czcionkę.
| div.news > p { font-size: 1.2em; } div.news > p:only-child { font-size: 1.5em; } |
Pierwszy selektor definiuje ogólną wielkość czcionki elementów <p>. Drugi z nich nadpisuje (ponieważ ma większą specyficzność) wielkość czcionki w przypadku, gdy akapit jest jedynym dzieckiem.
Podobnie do :only-child, pseudoklasa :only-of-type oznacza, że istnieje tylko jeden element danego typu.
Do czego może się przydać taka pseudoklasa? Wyobraź sobie sekwencję DIV-ów, spośród których kilka zawiera tylko jeden obrazek, a inne mają po kilka. Jeśli chcesz, by „pojedynczy” obrazek był wyśrodkowany, natomiast, gdy jest ich kilka, aby były przyciągnięte do lewej strony, możesz wykorzystać :only-of-type tak, jak w poniższym przykładzie.
| div.post > img { float: left; } div.post > img:only-of-type { float: none; margin: auto; } |
:empty reprezentuje element, który jest pusty. Można do wykorzystać, aby ukryć elementy, które mogą być puste.
| #sidebar .box:empty { display: none; } |
Jeśli w elemencie będzie znajdowała się nawet pojedyczna spacja lub znak nowej linii, nie będzie on traktowany jak pusty.
Dopiero ósme wydanie IE obsługuje strukturalne pseudoklasy. Działają one także w najnowszych wersjach Firefoxa, Safari oraz Opery.
Pseudoklasa negacji :not() pozwala odnosić się do elementów, które nie pasują do selektora w nawiasie.
Przykładowo, jeśli chcesz nadać styl wszystkim elementom input, oprócz tych, które są guzikami „submit”, możesz skorzystać poniższego selektora.
| input:not([type="submit"]) { width: 200px; padding: 3px; border: 1px solid #000000; } |
Kolejny przykład: chcesz ustalić większą czcionkę wszystkim akapitom, oprócz tego, który wyświetla datę i czas? Nic prostszego:
| p:not(.date) { font-size: 13px; } |
Pseudoklasa :not() nie jest obsługiwana nawet przez IE8. Niestety, oznacza to, że minie prawdopodobnie jeszcze sporo czasu zanim zacznie się ona często pojawiać w naszych arkuszach CSS.
Użycie pseudoelementów to sposób na odniesienie się do elementów, które tak naprawdę nie istnieją w kodzie HTML, takich jak pierwsza litera czy też pierwsza linia bloku tekstu.
Pseudoelementy występowały w CSS 2.1, ale specyfikacja trzeciego wydania określa, że powinny być zapisywane z podwójnym dwukropkiem, dla odróżnienia od pseudoklas. Te pseudoelementy, które występowały w CSS 2.1, były zapisywane przy użyciu pojedynczego dwukropka, przeglądarki powinny więc obsługiwać obydwa sposoby zapisu („:” oraz „::”). Natomiast nowe pseudoelementy, wprowadzone w CSS3, będą musiały być zapisywane tylko i wyłącznie z podwójnym dwukropkiem.
Odnosi się do pierwszej linii bloku lub nagłówka/elementu tabeli.
Najczęściej jest stosowany, aby „upiększyć” blok tekstu, np. zmieniając pierwszą linię w kapitaliki.
| h1 + p::first-line { font-variant: small-caps; } |
Jeśli czytałeś dokładanie ten artykuł, wiesz z pewnością, że powyższy selektor odnosi się do pierwszej linii akapitu, który występuje zaraz za tagiem <h1>.
Krokiem dalej jest zmiana stylu konkretnego akapitu, w tym przypadku pierwszego dziecka DIV-a o klasie post.
| div.post > p:first-child::first-line { font-variant: small-caps; } |
Ten pseudoelement odnosi się do pierwszego znaku (litery) danego bloku tekstu. Podobnie jak ::first-line jest często stosowany, aby wyróżnić ten element tekstu. Jeśli zastosujesz oba pseudoelementy, zarówno ::first-letter, jak i ::first-line, właściwości tego pierwszego będą ważniejsze niż te, odziedziczone od ::first-line.
| p { font-size: 12px; } p::first-letter { font-size: 24px; float: left; } |
Ten selektor ma najdłuższą specyfikację, spośród wszystkich w CSS. Warto przeczytać ją przed zastosowaniem tego pseudoelementu (to odnosi się także do każdego innego, który stosujesz).
::before oraz ::after są stosowane, aby dodać treści do dokumentu poprzez CSS. Treść wstawiona odziedziczy większość właściwości elementu, do którego jest wstawiana.
Teraz wyobraź sobie, że do opisu każdego z wykresów na Twojej stronie chcesz dodać tekst „Wykres numer X”. Możesz osiągnąć to bez konieczności stosowania języków skryptowych, a nawet bez ingerencji w HTML.
| .post { counter-reset: image; } p.description::before { content: "Wykres numer " counter(image) ": "; counter-increment: image; } |
Ale o co chodzi? Najpierw tworzymy licznik o nazwie image. Następnie, przed każdym akapitem o klasie description wstawiamy, korzystając z pseudoelementu ::before treść „Wykres numer” oraz obecną wartość licznika. Dodatkowo, po każdym użyciu należy wartość licznika inkrementować (counter-increment: image;).
:before oraz ::after są najczęściej stosowane z właściwością content, aby dodać krótkie zdania lub elementy do określonych miejsc na stronie. W powyższym przykładzie pokazałem, jak można je wykorzystać w poważniejszych zadaniach.
Pseudoelementy są obsługiwane przez IE8, pod warunkiem zapisu z jednym dwukropkiem. Wszystkie inne przeglądarki również obsługują te selektory.
Jeśli przebrnąłeś przez gąszcz pseudoklas, pseudoelementów i innych dziwnych selektorów, nadszedł czas abyś wypróbował je w praktyce. W razie problemów, czytaj specyfikacje W3C i pytaj na naszym forum.
A jeśli masz ochotę na eksperymenty, do swojego następnego projektu, zamiast stosować klasy i identyfikatory, przemyć kilka spośród opisanych selektorów CSS. Obiecuję, już nigdy nie będziesz chciał komplikować swojego kodu tymi niepotrzebnymi klasami i ID.
• Keeping Your Elements’ Kids in Line with Offspring — A List Apart
• Selectutorial - CSS selectors
• A Look at Some of the New Selectors Introduced in CSS3
• Selektory CSS 2.1, część pierwsza i druga
• CSS 3 selectors explained
• CSS selectors and pseudo selectors browser compatibility
• 10 Useful CSS Properties Not Supported By Internet Explorer
• Styling a Poem with Advanced CSS Selectors