Numeracja markerów list uporządkowanych
21 maja 2007
Numeracja list uporządkowanych domyślnie jest automatyczna - po wpisaniu znaczników ol i li przeglądarka doda markery w postaci liczb. Jest to zachowanie wymuszone przez style przeglądarki - ustawiony odpowiednio list-style-type (decimal).
Jednak rozpoczęcie liczenia zaczyna się zawsze od 1 i postępuje o tyle samo w górę. Na kartce papieru bez przeszkód mogę zacząć listę od "4.", aby w Wordzie zmienić środkowy numer na 20 wystarczy parę klików. Czy da się to zrobić w HTML?
Do niedawna dało się niesamowicie prosto - wystarczyło zapoznać się z atrybutami start i value. Pierwszy dodany do ol zaczynał liczenie od ustawionej wartości, drugi pozwalał zmienić numer pozycji listy nawet w jej środku.
Ale z różnych powodów (z którymi nie do końca się zgadzam) zostały w ścisłej definicji dokumentu wykreślone. Więc albo używamy nijakiego Transitional albo generujemy błędy składni.
Można rozwiązać problem na dwa sposoby.
Counters
Pierwszy wiąże się z użyciem generowanej zawartości oraz liczników CSS, które odpowiednio ustawione stworzą numerowanie. Wspierają je Opera i Firefox, z czego tylko pierwsza przeglądarka radzi sobie też dobrze z samą GC.
Potrzebujemy zapoznać się z 2 właściwościami: counter-reset, counter-increment oraz funkcją counter(). Wszystkie trzy operują na identyfikatorze licznika, dowolnie nazwanego. W przykładzie użyję "start".
ol {counter-reset: start;}ol li {list-style-type: none;counter-increment: start;}ol li::before {content: counter(start) ". ";}
Co tu się dzieje?
Pierwsza reguła ustawia przez
counter-resetlicznikstartdla listy uporządkowanejol. Także resetuje go za każdym znalezieniem kolejnegool.Druga reguła przez
counter-incrementzwiększa licznik przy każdym napotkaniu pozycji listyli.Trzecia reguła wykorzystuje wreszcie GC aby umieścić dane w dokumencie - zmienną licznika (oraz kropkę i spację).
Gdy odpalimy test takiego kodu zobaczymy, że otrzymaliśmy standardowe numerowanie.
Natomiast to nie koniec bojów - numerowanie nie jest ładnie wyrównane, pozycje listy nie są wcięte i wszystko wygląda jakbyśmy dopisali te numery w HTML. W jaki sposób umieścić liczniki jako markery?
Według specyfikacji powinniśmy użyć display: marker, ale wsparcie tej właściwości leży i opala się na Hawajach. Można spróbować użyć display: inline-block, nadać szerokość, mały odstęp i wyrównanie do prawej. Za trudne to jednak dla Firefoksa, a i tak nie jesteśmy w stanie wciąć tekstu listy.
Skorzystałem wreszcie z wyświetlania tabelowego.
ol li {display: table-row;}ol li:before {display: table-cell;width: 40px;text-align: right;padding-right: 1ex;}
Test. Tym razem Opera ładnie renderuje listę. Firefox zapomina o licznikach. Normalnie idę się pociąć czerstwą bułką.
Oznacza to mniej więcej, że jakieś standardy istnieją i teoretycznie można zamienić przestarzałe atrybuty na odpowiedniki CSS-owe zachowując odpowiedni układ. Ale nawet najnowsze przeglądarki jeszcze nie są na to gotowe. Pozostaje więc tylko jedno.
JavaScript
Skorzystać ze skryptu, który sprawdzi odpowiednie elementy w poszukiwaniu, dajmy na to, klasy i zaaplikuje atrybuty. Co zyskujemy? Tylko przejście walidacji. Czasem jednak jest to wymagane. Czasami też jesteśmy świadomi, że pozostała część naszego kodu jest tak dobrej jakości, że nie opłaca się schodzić w dół z DOCTYPE.
Napisałem kawałek kodu JS, który szuka w HTML takich konstrukcji:
<ol class="start:100"><li class="value:1">
I dodaje automatycznie obok odpowiednie atrybuty. Działa także z ujemnymi wartościami. Całość jest bardzo szybka, bo wykonuje się przed window.onload1 i działa na każdej przeglądarce, włącznie z IE.
Powiedziałem każdej? Safari ma jakieś problemy z dodaniem atrybutu start w JS - pomysły? Tak czy inaczej, działające demo.
Zaznaczę jeszcze raz na koniec - nie jestem zwolennikiem obchodzenia w JavaScript błędów walidacji, tutaj jednak wszystkie inne sposoby zawiodły. Dodatkowo klasy w pewien sposób oddają znaczenie elementu - tylko wygląd zmieniamy w JS zamiast w CSS.
- 1) więcej w następnym wpisie