
CSS Is Awesome by Steven Frank (http://stevenf.tumblr.com/)
Pisząc aplikacje internetowe najczęściej opieramy się na podstawowych, często występujących selektorach CSS. Są to głównie selektory id, atrybutu class oraz potomka, plus pseudo-selektory, np :hover. Pliki .css w wielu projektach są pisane dość zachowawczo. Warto zatem zapoznać się z większą liczbą możliwości, które czasami mogą usprawnić pisanie reguł, ograniczych ich ilość, zmniejszyć objętość kodu.
Najczęściej stosowane selektory
- Uniwersalny
- Typu
- Identyfikatora
- Klasy
Łączniki, selektory atrybutów
- Potomek
- Dziecko
- Rodzeństwo
- Selektor atrybutu
Pseudo-klasy, pseudo-elementy
- Pseudo-klasa :first-child
- Pseudo-klasy linków :link i :visited
- Dynamiczne pseudo-klasy :hover, :acitve, :focus
- Pseudo-klasy języka :lang
- Pseudo-elementy :first-line, :first-letter, :before i :after
Najczęściej stosowane selektory
Uniwersalny
Selektor uniwersalny pasuje do wszystkich elementów (każdego typu), zastosowany najprostszy metaznak *
(asterisk) oznaczający dowolne dopasowanie.
Jeśli selektor uniwersalny jest jednym z kilku składników wyrażenia, to można go pominąć. *.mojaklasa
będzie równoważne z .mojaklasa
.
Obecnie stosuje się go najczęściej w przypadku dyrektyw resetujących Reset CSS.
* {margin: 0; padding: 0; border: 0;} |
* {margin: 0; padding: 0; border: 0;}
<strong>Ten element zostanie dopasowany</strong>
<div>Ten element też zostanie dopasowany</div> |
<strong>Ten element zostanie dopasowany</strong>
<div>Ten element też zostanie dopasowany</div>
Typu
Selektor typu dopasowuje elementy drzewa DOM po nazwie. Wybiera wszystkie elementy danego typu w całym drzewie dokumnetu.
div {margin: 10px; padding: 10px; border: 1px solid silver;} |
div {margin: 10px; padding: 10px; border: 1px solid silver;}
<div>Ten element zostanie dopasowany</div>
<strong>Ten element nie zostanie dopasowany</strong> |
<div>Ten element zostanie dopasowany</div>
<strong>Ten element nie zostanie dopasowany</strong>
Identyfikatora
Selektor identyfikatora poprzedza się znakiem #
. Pobiera on element o id równym podanemu ciągowi znaków po #. Z definicji w dokumencie może występować tylko jeden element o danym id. Zatem selektor identyfikatora pobiera tylko jeden element.
#identyfikator { margin: 10px;} |
#identyfikator { margin: 10px;}
<strong id="identyfikator">Ten element zostanie dopasowany</strong>
<div>Ten element nie zostanie dopasowany</div> |
<strong id="identyfikator">Ten element zostanie dopasowany</strong>
<div>Ten element nie zostanie dopasowany</div>
Klasy
Selektor klasy w przeciwieństwie do selektora identyfikatora nie musi być unikalny, zatem swoim zasięgiem może obejmować więcej niż jeden element. Dopasowuje elementy na podstawie atrybutu class. Selektor poprzedza się znakiem .
Jest niezależny od typu czy identyfikatora.
<strong class="klasa">Ten element zostanie dopasowany</strong>
<div>Ten element nie zostanie dopasowany</div> |
<strong class="klasa">Ten element zostanie dopasowany</strong>
<div>Ten element nie zostanie dopasowany</div>
Wartym uwagi jest fakt łączenia kilku selektorów klasy dla jednego elementu. Działanie to ma na celu wyłuskanie tylko tych elementów, które zawierają wszystkie z podanych klas.
.zolty.niebieski { color: green;} |
.zolty.niebieski { color: green;}
<strong class="zolty niebieski">Ten element zostanie dopasowany</strong>
<strong class="zolty">Ten element nie zostanie dopasowany</strong>
<strong class="niebieski">Ten element nie zostanie dopasowany</strong> |
<strong class="zolty niebieski">Ten element zostanie dopasowany</strong>
<strong class="zolty">Ten element nie zostanie dopasowany</strong>
<strong class="niebieski">Ten element nie zostanie dopasowany</strong>
Łączniki, selektory atrybutów
Wszystkie poniższe selektory z wyjątkiem ostatniego są przez niektórych określane łącznikami, czyli selektorami powstałymi poprzez połączenie ze sobą dwóch lub więcej selektorów podstawowych.
Łączenie następuje poprzez zastosowanie znaków białych (spacje) znaku >
oraz +
.
Potomek
Selektor potomka jest bardzo często stosowany. Zdarza się, że zastosowany selektor potomka jest uznawany po prostu za następujące po sobie selektory typu. Selektor ten oddziela selektory typu znakiem białym, pobiera elementy, które są potomkami elemenu pasującego do poprzedniego selektora. Jest przy tym niezależny od klas i identyfikatorów, zatem przy jego pomocy można ostylować wiele elementów bez dodawania zbytecznych atrybutów. Oczywiście istnieje możliwość łączenia selektorów typu wraz z selektorami klas i identyfikatorów.
Poniższy przykład dopasuje element p
będący potomkiem elementu div
.
<div>
Ten element zostanie dopasowany
<ul>
<li>
Ten element też zostanie dopasowany</li>
</ul>
</div> |
<div>
Ten element zostanie dopasowany
<ul>
<li>
Ten element też zostanie dopasowany</li>
</ul>
</div>
Dziecko
Selektor dziecka bywa często niedoceniany lub mylony z selektorem potomka. Różnica wbrew pozorom jest znacząca: selektor dziecka odnosi się tylko do bezpośredniego potomka. Znakiem stosowanym w tym selektorze jest >
.
div > p {color: #ff0000;} |
div > p {color: #ff0000;}
<div>
Ten element zostanie dopasowany
<ul>
<li>
Ten element nie zostanie dopasowany</li>
</ul>
</div> |
<div>
Ten element zostanie dopasowany
<ul>
<li>
Ten element nie zostanie dopasowany</li>
</ul>
</div>
Rodzeństwo
Selektor rodzeństwa lub inaczej zwany selektorem sąsiednim tworzony jest poprzez zastosowanie znaku +
jako łącznika. Dopasowuje on element, który jest rodzeństwem pierwszego podanego elementu (oba mają tego samego rodzica), pierwszy z nich występuje przed drugim. Stosuje się go jako pseudo-klasę, którą można by nazwać :second-child
li + li {coloer: #ff0000; } |
li + li {coloer: #ff0000; }
<div>
<ul>
<li>Ten element nie zostanie dopasowany</li>
<li>Ten element zostanie dopasowany</li>
</ul>
</div> |
<div>
<ul>
<li>Ten element nie zostanie dopasowany</li>
<li>Ten element zostanie dopasowany</li>
</ul>
</div>
Selektor atrybutu
Selektor atrybuty jest zbliżony do selektora identyfikatora i klasy, z tego powodu znajduje się w tej grupie. Dopasowuje on elementy na podstawie wartości wybranych atrybutów lub po prostu ich występowania. Możliwości dopasowania są 4.
Dopasowuje elementy, które posiadają dany atrybut, bez znaczenia jego zawartości:
a[href] {text-decoration: underline;} |
a[href] {text-decoration: underline;}
<a href="http://blog.vokiel.com">Ten element zostanie dopasowany</a>
<a id="tennie">Ten element nie zostanie dopasowany</a> |
<a href="http://blog.vokiel.com">Ten element zostanie dopasowany</a>
<a id="tennie">Ten element nie zostanie dopasowany</a>
Dopasowuje elementy, które posiadają dany atrybut, a jego wartość jest zgodna z określoną:
a[rel=follow] {text-decoration: underline;} |
a[rel=follow] {text-decoration: underline;}
<a rel="follow" href="http://blog.vokiel.com">Ten element zostanie dopasowany</a>
<a rel="nofollow" href="http://google.pl">Ten element nie zostanie dopasowany</a> |
<a rel="follow" href="http://blog.vokiel.com">Ten element zostanie dopasowany</a>
<a rel="nofollow" href="http://google.pl">Ten element nie zostanie dopasowany</a>
Dopasowuje elementy, które posiadają dany atrybut, a jedną z jego wartości oddzielonych spacjami jest ta podana. Różni się od =
tym, że nie sprawdza dokładnego dopasowania całej wartości atrybutu, a wyszukuje w wartościach oddzielonych spacjami:
a[rel~=copyleft] {text-decoration: underline;} |
a[rel~=copyleft] {text-decoration: underline;}
<a rel="copyright copyleft copyeditor" href="http://blog.vokiel.com">Ten element zostanie dopasowany</a>
<a rel="copyright" href="http://google.pl">Ten element nie zostanie dopasowany</a> |
<a rel="copyright copyleft copyeditor" href="http://blog.vokiel.com">Ten element zostanie dopasowany</a>
<a rel="copyright" href="http://google.pl">Ten element nie zostanie dopasowany</a>
Dopasowuje elementy, które posiadają dany atrybut, a jego wartość jest listą wartości rozdzielonych znakiem minus. Lista ta rozpoczyna się podaną wartością. Stosuje się do dopasowania kodów języka, określonych w atrybucie lang (zobacz :lang.
p[lang|=en] {text-decoration: underline;} |
p[lang|=en] {text-decoration: underline;}
Ten element zostanie dopasowany
Ten element zostanie dopasowany
Ten element zostanie dopasowany
Ten element nie zostanie dopasowany |
Ten element zostanie dopasowany
Ten element zostanie dopasowany
Ten element zostanie dopasowany
Ten element nie zostanie dopasowany
Pseudo-klasy, pseudo-elementy
Jak sama nazwa wskazuje pseudo-klasy i pseudo-elementy są pesudo selektorami. Nie dopasowują elementów na podstawie nazwy, atrybutów czy też zawartości. Ich dopasowanie odbywa się niejawnie. Mają one za zadanie dać możliwość wyboru elementów, bez konieczności opakowywanie ich w dodatkowe atrybuty.
Pseudo-klasa :first-child
Dopasowuje element, który jest pierwszym dzieckiem innego elementu. Zastosowań tej pseudo-klasy może być bardzo wiele. Często mając różnego rodzaju listy chcemy wyszczególnić pierwszy element, tworząc menu na liście zdarza się, że pierwszy element ma być delikatnie inaczej ostylowany, czy pierwszy paragraf w tekście.
li:first-child { border-left: 1px solid silver; } |
li:first-child { border-left: 1px solid silver; }
<ul>
<li>Ten element zostanie dopasowany</li>
<li>Ten element nie zostanie dopasowany</li>
</ul> |
<ul>
<li>Ten element zostanie dopasowany</li>
<li>Ten element nie zostanie dopasowany</li>
</ul>
Wraz z CSS3 doszły nowe pseudo-elementy: :last-child
oraz :nth-child
Pseudo-klasy linków :link i :visited
Do tej kategorii zalicza się dwie pseudo-klasy: :link
oraz :visited
. Ich ostylowanie zależy od przeglądarki, pierwszy z nich oznacza linki, które jeszcze nie zostały odwiedzone przez klienta, drugi oznacza te, które już klient odwiedził.
Dynamiczne pseudo-klasy :hover, :acitve, :focus
Dynamiczne pseudo-klasy, jak sama nazwa wskazuje, są nadawane dynamiczne podczas wykrywania interakcji z użytkownikiem. Obsługują takie akcje jak: najechanie kursorem myszy na element :hover
, aktywność danego elementu – w przypadku użycia myszki oznazcza, że przycisk został naciśnięty ale jeszcze nie zwolniony. Ostani z trójki: :focus
obowiązuje dla aktywnego elementu, czyli np pola formularza, w którym aktualnie znajduje się kursor myszy oczekujący na wpisywane przez użytkownika znaki.
a:hover{ text-decoration: underline; } |
a:hover{ text-decoration: underline; }
<a href="http://blog.vokiel.com">Ten element zostanie podkreślony po najechaniu na niego kursorem myszki.</a> |
<a href="http://blog.vokiel.com">Ten element zostanie podkreślony po najechaniu na niego kursorem myszki.</a>
a:active{ font-weight: bold; } |
a:active{ font-weight: bold; }
<pre lang="html"><a href="http://blog.vokiel.com">Ten element zostanie pogrubiony po wciśnięciu klawisza myszki (do czasu zwolnienia).</a> |
<pre lang="html"><a href="http://blog.vokiel.com">Ten element zostanie pogrubiony po wciśnięciu klawisza myszki (do czasu zwolnienia).</a>
input:focus{ background: #ff0000; } |
input:focus{ background: #ff0000; }
<input type="text" value="Tło zrobi się czerwone po umieszczeniu kursora w jego wnętrzu" /> |
<input type="text" value="Tło zrobi się czerwone po umieszczeniu kursora w jego wnętrzu" />
Pseudo-klasy języka :lang
Tą pseudo-klasą oznacza się elementy zawierające tekst w innym języku. Umożliwa inne ostylowanie elementów w zależności od języka. Często stosuje się do ustawienia cudzysłowów. Dopasowanie odbywa się podobnie jak w przypadku selektora atrybuty użytego z tyldą (nie tylko dokładne dopasowanie, ale także wyszukanie w ciągu). Identyfikator języka nie musi być poprawną nazwą języka, ale musi być wypełniony.
:lang(fr) > p { quotes: '« ' ' »' } |
:lang(fr) > p { quotes: '« ' ' »' }
:lang(de) > p { quotes: '»' '«' '\2039' '\203A' } |
:lang(de) > p { quotes: '»' '«' '\2039' '\203A' }
Pseudo-elementy :first-line, :first-letter, :before i :after
Pseudo-elementy zachowują się jak zwykłe znaczniki CSS – dają możliwość ostylowania części zawartosci elementów na podstawie właściwości, których określenie następuje dynamicznie. Pierwszy z nich :first-line
odnosi się do zawartości pierwszej linii danego paragrafu. Ważną informacją w tym miejscu jest lista ograniczeń, ten pseudo-element może zmieniać tylko niektóre parametry: font-, color-, background-, word-spacing, letter-spacing, text-decoration, vertical-align, text-transform, line-height
.
p:first-line {font-weight: bold;} |
p:first-line {font-weight: bold;}
Ta pierwsza linia będzie pogrubiona,
następne już nie, bo nie zostaną objęte
znacznikiem :first-line |
Ta pierwsza linia będzie pogrubiona,
następne już nie, bo nie zostaną objęte
znacznikiem :first-line
Jeśli pierwszy wiersz miałby zostać rozbity na kilka linii, a chcielibyśmy aby całe pierwsze zdanie było inaczej ostylowane możemy posiłkować się dodaniem pseudo-atrybutu w kodzie, dla danego elementu:
Ta pierwsza linia będzie pogrubiona,
aż do tego miejsca, następne już nie bo nie zostaną
objęte znacznikiem :first-line |
Ta pierwsza linia będzie pogrubiona,
aż do tego miejsca, następne już nie bo nie zostaną
objęte znacznikiem :first-line
Należy przy tym uważać na znaki rozpoczynające nowe linie. Przykładowo w kodzie poniżej, żadne znaki nie zostaną odmiennie ostylowane, ponieważ pierwsza linia nie ma zawartości:
Nic tu nie zostanie odmiennie ostylowane,
tym bardziej następne linie.
Kolejny :first-letter
działa analogicznie do poprzedniego, z tą różnicą, że daje możliwość ostylowania pierwszej litery zamiast pierwszej linii. Stosowanie tego pseudo-elementu zostało ogranioczne do elementów blokowych (block, list-item, table-cell, table-catpion, inline-block). Dodatkowo istnieje podobne ograniczenie jak w przypadku first-line: zmiany ostylowania mogą obejmować: font-, word-spacing, letter-spacing, text-decoration, vertical-align, text-transform, line-height, float, margin-, padding-, border-, color-, background-
p:first-letter {font-size: 26px;} |
p:first-letter {font-size: 26px;}
Tylko pierwsza literka T z tego paragrafu będzie powiększona do rozmiru 26px. |
Tylko pierwsza literka T z tego paragrafu będzie powiększona do rozmiru 26px.
Pseudo-selektory :before
i :after
są używane do wstawiania wygenerowanej treści przed lub za wybrany element.
blockquote:before {content: "Cytat:";} |
blockquote:before {content: "Cytat:";}
<blockquote>
Ten cały cytat zostanie poprzedzony słowem "Cytat:".</blockquote> |
<blockquote>
Ten cały cytat zostanie poprzedzony słowem "Cytat:".</blockquote>
a[href~=http]:after { background: url("outgoing.png") no-repeat center right;} |
a[href~=http]:after { background: url("outgoing.png") no-repeat center right;}
<a href="http://blog.vokiel.com">Ten link dostanie ikonkę na końcu</a>
<a href="#selektor-uniwersalny">Ten już nie</a> |
<a href="http://blog.vokiel.com">Ten link dostanie ikonkę na końcu</a>
<a href="#selektor-uniwersalny">Ten już nie</a>
Źródła
Tyle teorii… A jak sprawa wygląda w praktyce? Czy przeglądarki (przynajmniej to najpopularniejsze) radzą sobie ze wszystkimi selektorami?
Większość selektorów CSS2 jest w pełni obsługiwana przez najnowsze przeglądarki. Problemy robi oczywiście IE6, który nie radzi sobie w pełni z: selektorem dziecka, rodzeństwa, atrybutu, klas wielokrotnych, pseudo-klasą :first-child, języków, :hover działa tylko dla linku a, :focus dla linku nie jest wspierany – zamiast tego jest :active, nie działają też pseudo-elementy :before i :after.
Tabela porównań jest dostępna u PPK: CSS contents and browser compatibility
Nie chcę nic mówić, ale z moich ostatnich testów selektora atrybutu(chciałem sobie jakoś estetyczniej ostylować formularz) wynika, że nie tylko IE6 ma z nim problem, ale wszystkie[!] jego wersje, nawet najnowszy IE 9. Na szczęście mamy takie rozwiązania jak ie-7js, które łatają te dziury 🙂
Pseudo elementy i pseudo klasy niestety nie są jeszcze we wszystkich przeglądarkach interpretowane identycznie. Dawno już weszło CSS3 a tu nie można w pełni CSS2 używać jeśli chce mieć się pewność identycznego wyglądu we wszystkich kombajnach…
Szczerze ja zabawę z budową CSS pod IE już dawno zakończyłem, bo widzę że za błędami w interpretacji po prostu nie dogoni człowiek… To microsroft powinien się stosować do standardów a nie internet do niego.