Wszystko, co musisz wiedzieć o licznikach w CSS!
[demo url=”http://edu3.home.pl/blog/pliki/csscounters/” files=”http://edu3.home.pl/blog/pliki/csscounters/csscounters.zip”] Choć wielu z nas każdego dnia pisze ogromne ilości kodu CSS, to nie zawsze wykorzystujemy pełen potencjał tej specyfikacji. Czasami świadomie…
[demo url=”http://edu3.home.pl/blog/pliki/csscounters/” files=”http://edu3.home.pl/blog/pliki/csscounters/csscounters.zip”]
Choć wielu z nas każdego dnia pisze ogromne ilości kodu CSS, to nie zawsze wykorzystujemy pełen potencjał tej specyfikacji. Czasami świadomie dlatego, że nie wszystkie nowości są jeszcze dobrze wspierane we wszystkich przeglądarkach internetowych. Czasami jednak nieświadomie, gdyż po prostu zwyczajnie nie wiemy, że pewne ułatwienia, które są od dawna dobrze wspierane, nas omijają.
W tym wpisie przedstawiamy CSS Counters, czyli technikę, która choć jest bardzo przydatna i działa bardzo dobrze we wszystkich obecnie liczących się przeglądarkach, to jest jednak stosunkowo rzadko wykorzystywana. Zakładamy zatem, że znajdzie się wiele osób, które tej techniki nie znają, stąd ten wpis.
CSS3? A skądże! CSS 2.1
Tak. CSS Counters obecne są z nami już od bardzo dawna, odkąd pojawiła się specyfikacja CSS 2.1. Na czym polega zatem cała zabawa? Jeśli programowałeś w jakimkolwiek języku, to wyobraź sobie następujący sceniariusz:
- tworzymy zmienną np.
list-counter
i ma ona domyślnie wartość0
- generując np. listę
ul
i jej elementyli
, zwiększamy wartość zmiennej o 1 - wyświetlamy otrzymaną wartość
W przypadku CSS, wszystkie te czynności wykonamy za pomocą dwóch właściwości i dwóch funkcji, a konkretnie (w kolejności jak powyżej):
counter-reset: list-counter;
counter-increment: list-counter;
counter(list-counter);
Generowanie numerów dla listy OL
Wyobraź sobie następujący kod
<ol> <li>Element listy</li> <li>Element listy</li> <li>Element listy</li> <li>Element listy</li> <li>Element listy</li> </ol>
Wiemy, że dla listy ol
możemy przypisać list-style-type: decimal
i zostanie ona automatycznie ponumerowana. My natomiast oczekujemy większej elastyczności, zatem usuniemy z niej domyślne numerowanie poprzez list-style-type: none
i wygenerujemy numerację samodzielnie.
Stworzone numerki będziemy chcieli wstawić za pomocą pseudo-elementu :before
, gdyż użycie wspomnianej wyżej funkcji counter
możliwe jest wyłącznie we właściwości content
. Jeśli nie wiesz jeszcze jak działają również świetnie wspierane pseudo-elementy :before
i :after
, to zapraszamy do przeczytania na ten temat na naszym blogu w tym miejscu.
Nasz kod CSS będzie zatem wyglądał następująco:
ol { counter-reset: list-counter; } ol li { padding-left: 20px; position: relative; counter-increment: list-counter; } ol li:before { content: counter(list-counter) "."; position: absolute; top: 0; left: 0; }
Jak zatem widzisz, w momencie przypisywania stylów dla elementu ol
tworzymy nowy licznik o nazwie list-counter
, następnie dla każdego elementu li
ten licznik zwiększamy, a później w pseudo-elemencie :before
wyświetlamy go za pomocą funkcji counter
. Zauważ również, za zaraz za funkcją podaliśmy spację i kropkę w cudzysłowie. W ten sposób możemy za wyświetloną wartością dodać coś więcej i zostanie to razem połączone. Zatem za numerkiem pojawi się kropka.
Dzięki użyciu w li
position:relative
, a dla :before
position: absolute
, mogliśmy ustawić numerek z lewej strony. Daje nam to dużo większą swobodę niż używanie list-style-type: decimal
, który nie jest dostępny dla innych elementów.
Wyobraź sobie, że na stronie mamy np. komentarze, które również chcemy ponumerować (zobacz DEMO). Wówczas dla ich kontenera przypiszemy counter-reset
, a dla każdego elementu (np. div
) counter-increment
i kolejno dla :before
lub :after
użyjemy funkcji counter
.
Nie tylko wartości liczbowe
Oprócz domyślnych wartości liczbowych, gdzie nasza lista zostanie ponumerowana jako 1, 2, 3, itd., możemy używać również innego formatowania. Dostępne są dla nas wszystkie możliwości dostępne w przypadku list-style-type
. A więc jeśli chcesz ponumerować listę lub np. komentarze za pomocą liczb rzymskich, możesz tego dokonać. Podobnie w przypadku bulletów itd.
Wybrany styl możesz podać jako drugi argument do funkcji counter
w ten sposób:
li:before { content: counter(list-counter, upper-roman); }
funkcja counters
Oprócz funkcji counter
, dostępna jest również funkcja counters
, która pozwala wyświetlać połączone wartości wielu liczników.
Spójrzmy na poniższy kod HTML:
<ol> <li> Element listy <ol> <li>Element zagnieżdżonej listy</li> <li>Element zagnieżdżonej listy</li> <li>Element zagnieżdżonej listy</li> </ol> </li> <li> Element listy <ol> <li>Element zagnieżdżonej listy</li> <li>Element zagnieżdżonej listy</li> </ol> </li> <li>Element listy</li> </ol>
A w kodzie CSS utworzymy sobie dwa liczniki o takiej samej nazwie, lecz na dwóch różnych poziomach zagnieżdżenia:
ol { counter-reset: list-counter; } ol li:before { counter-increment: list-counter; content: counter(list-counter) "."; } ol li ol { counter-reset: list-counter; }
W tym momencie list-counter
przyjmie wartość 0
dla nadrzędnej listy ol
. Następnie będzie zwiększany o 1
dla każdego pseudo-elementu :before
w elemencie li
(nie tylko bezpośrednich w nadrzędnej liście ol
, ale dla wszystkich). Można zatem powiedzieć, że :before
pobiera sobie wartość licznika i po prostu go zwiększa. Natomiast skąd bierze tę wartość? Otóż szuka jej idąc do góry. Zatem przy powyższym zapisie, za każdym razem gdy „wejdziemy” do elementu ol
zagnieżdżonego w innym elemencie li
, resetujemy licznik do wartości 0
. Nie resetujemy jednak tego, który był utworzony wyżej (idea zagnieżdżonej pętli).
W tym momencie w :before
dla elementu ol li ol li
będziemy mieli zupełnie inną wartość i taka właśnie zostanie wstawiona we właściwości content
.
W tym momencie zostanie wygenerowana tego typu lista:
1. Element listy 1.Element zagnieżdżonej listy 2. Element zagnieżdżonej listy 3. Element zagnieżdżonej listy 2. Element listy 1. Element zagnieżdżonej listy 2. Element zagnieżdżonej listy 3. Element listy
My chcielibyśmy natomiast podsekcje numerować numerem nadrzędnym, kropką i numerem aktualnym, np. 1.2.
W tym momencie z pomocą przychodzi nam funkcja counters
. W niej podajemy nazwę licznika, jako drugi parametr w cudzysłowie separator, a jako trzeci, opcjonalnie wybrany styl. W ten sposób wszystkie wartości zostaną połączone wybranym separatorem („” jeśli nie chcesz używać separatora).
Całość będzie wyglądała następująco:
ol { counter-reset: list-counter; } ol li:before { counter-increment: list-counter; content: counters(list-counter, ".") "."; } ol li ol { counter-reset: list-counter; }
A na stronie w ten sposób:
1. Element listy 1.1. Element zagnieżdżonej listy 1.2. Element zagnieżdżonej listy 1.3. Element zagnieżdżonej listy 2. Element listy 2.1. Element zagnieżdżonej listy 2.2. Element zagnieżdżonej listy 3. Element listy
Co jeszcze warto wiedzieć?
Jest jeszcze kilka istotnych kwestii, które warto poznać. Na początku wspomnieliśmy, że po użyciu counter-reset: nazwa-licznika
, przyjmie on wartość 0
. Możemy to natomiast zmienić, po spacji podając żądaną wartość np. counter-reset: list-counter 2
.
W ten sposób startujemy od wartości 2
. Możemy podawać również ujemne wartości, poprzedzając je oczywiście znakiem minusa.
Kolejną rzeczą jest możliwość resetowania kilku liczników jednocześnie, w taki sposób: counter-reset: licznik-pierwszy 2 licznik-drugi 10
. Możemy w ten sposób przypisać im wartości lub pominąć przypisywanie wartości i ustawić je domyślnie na 0
.
Jeśli chodzi o zwiększanie wartości poprzez counter-increment
, to również nie musimy tego robić „o jeden”. Poprzez zapis counter-increment: list-counter 3
, zwiększymy wartość licznika list-counter
do wartości 3
, następnie 6
itd. Podobnie jak w przypadku counter-reset
, również możemy zwiększyć kilka liczników poprzez counter-increment: licznik-pierwszy licznik-drugi 3
.
Na koniec bardzo istotną kwestią jest fakt, że elementy, które mają przypisaną właściwość display: none
, nie mogą ani resetować, ani zwiększać liczników. Nie zadziała zatem zapis:
li { display: none; counter-increment: list-counter; }
Podsumowanie
Jak zatem widzisz, liczniki w CSS to świetne narzędzie, które w połączeniu z pseudo-elementami daje duże pole do popisu. Koniecznie sprawdź nasze DEMO i poeksperymentuj z CSS Counters!