Tutorial

Marcin Warpechowski


Jak przy pomocy CSS ograniczyć grafikę wykorzystywaną na stronie do kilku plików. Dla przykładu zbudujemy prosty pasek narzędzi. Później zmodyfikujemy go trochę, zaprzęgając do pracy JavaScript.

Numer 15 (1/2006) • 25 stycznia 2006


Jinyoung Shin : Minigaleria

Marcin Warpechowski. Kafelkowanie z CSS.

Ilustracja: Jinyoung Shin


Kafelkowanie z CSS


CSS daje wiele możliwości kontroli wyglądu strony. Niestety, niewiele osób uwalnia swoją wyobraźnię i jego użycie ogranicza się zwykle do prostego formatowania tekstu. Pójdźmy więc dalej, zapanujmy też nad grafiką!

Dzisiejsi użytkownicy nie znoszą kompromisów. Oczekują doskonałego przedstawienia informacji, krótkiego czasu ładowania, odpowiedniej użyteczności i dostępności serwisów WWW. Jednak wraz ze wzrostem złożoności serwisów internetowych, webdeveloperzy stają przed problemem rosnącej objętości kodu HTML i wydłużającej się listy plików graficznych ładowanych razem ze stroną. W takim momencie z pomocą przychodzą kafelki.

Artykuł adresuję do czytelników średniozaawansowanych. Dowiesz się z niego jak przy pomocy CSS ograniczyć grafikę wykorzystywaną na stronie do kilku plików. Dla przykładu zbudujemy prosty pasek narzędzi (przykład 1). Później zmodyfikujemy go trochę, zaprzęgając do pracy JavaScript (przykład 2).

Czym są kafelki i co w nich dobrego

Choć wynalazłem to pojęcie na potrzeby artykułu, sama idea nie jest wcale taka nowa. Międzynarodowej publiczności termin ten jest znany jako sprites, a jego premiera w ujęciu styli kaskadowych miała miejsce w artykule CSS Sprites: Image Slicing's Kiss of Death na łamach ALA.

Pomysł na kafelkowanie za pomocą CSS nie jest skomplikowany. Wyobraźmy sobie plik graficzny, który zawiera w sobie wiele podobnych części, jakie składają się na wygląd strony. Mogą to być części layoutu, przyciski lub inna grafika wykorzystywana na stronie. W naszym przypadku będą to ikony paska narzędzi:

Pierwsza grafika użyta w przykładach

Wszystkie ikony mieszczą się w kwadratach o wymiarach 25×25px i zostały umieszczone w 2 rzędach: pierwszy odpowiada za normalną postać przycisku, a drugi za rollover (widoczny po najechaniu kursorem)

Główną zaletą użycia metody kafelków jest oszczędność czasu:

Zaspokajamy podstawowe potrzeby

Pierwszych pięć kafelków to ikony odnośników do serwisów internetowych. Załóżmy, że istnieje powód dla którego ktoś chciałby mieć na swojej stronie pasek z podobnymi ikonami. Stwórzmy więc pasek narzędzi spełniający poniższe założenia:

Zacznijmy od grafiki paska narzędzi, która podobnie jak ikony przycisków, mieści się w jednym pliku:

Druga grafika użyta w przykładach

Powyżej widzimy cztery kafelki o takiej samej wysokości 26px, lecz nierównej długości:

Kafelki z drugiego rzędu mają znaczenie kosmetyczne i są ładowane za pomocą specjalnych klas:

  1. <ul class="toolbar">
  2. <li class="left">-</li>
  3. <li></li>
  4. <li></li>
  5. <li></li>
  6. <li class="separator">-</li>
  7. <li></li>
  8. <li></li>
  9. <li class="right">-</li>
  10. </ul>

Style definiujące wygląd tych dodatkowych kafelków wyglądają tak:

  1. .toolbar {
  2. padding: 0;
  3. margin: 0;
  4. list-style: none;
  5. }
  6. .toolbar li {
  7. float: left;
  8. height: 26px;
  9. background-position: 0 0%;
  10. background-image: url(toolbar.png);
  11. background-repeat: no-repeat;
  12. text-indent: -999em;
  13. }
  14. .toolbar li.left {
  15. background-position: 0 100%;
  16. width: 2px;
  17. }
  18. .toolbar li.separator {
  19. background-position: -2px 100%;
  20. width: 4px;
  21. }
  22. .toolbar li.right {
  23. background-position: -6px 100%;
  24. width: 2px;
  25. }

Nasze przyciski zamieścimy wewnątrz zwykłych znaczników <li></li>, dlatego w CSS przypisaliśmy temu znacznikowi wyświetlanie górnej części pliku (background-position: 0 100%;), zawierającej tło paska narzędzi.

Dodatkowe części paska, takie jak <li class="left">-</li> są odpowiednio wykadrowane za pomocą atrybutów background-position i width.

Teraz, gdy już mamy pasek, pozostaje nam tylko wypełnić puste znaczniki odnośnikami. Pierwszy z nich wyglądać będzie tak:

  1. <li>
  2. <a class="wbstm" title="idź do Webesteem" href="http://www.webesteem.pl/">
  3. Webesteem
  4. </a>
  5. </li>

Przyciski umieszczamy w osobnych <li>, w postaci odnośników <a> z własną klasą i tytułem (wyświetlanym w dymku po najechaniu nad przycisk kursorem). W środku odnośnika znajduje się znacznik <span>, zawierający tekst alternatywny, który oczywiście ukrywamy za pomocą styli.

Wszystkie przyciski wykorzystują wspólny styl:

  1. .toolbar li a {
  2. display: block;
  3. width: 25px;
  4. height: 25px;
  5. background-image: url(toolbar-buttons.png);
  6. background-repeat: no-repeat;
  7. }

Spójrzmy na styl klasy "wbstm", kadrujący ikonę dla pierwszego przycisku:

  1. .toolbar a.wbstm {
  2. background-position: 0 0%;
  3. }
  4. .toolbar a.wbstm:hover {
  5. background-position: 0 100%;
  6. }

Jak widać, nie jest to wcale skomplikowane. W podobny sposób deklarujemy pozostałe przyciski, za każdym razem przesuwając obrazek tła o 25px. Oznacza to, że ikonę drugiego przycisku wykadrujemy za pomocą: background-position: -25px top;

No, ale dość tego gadania. Zobacz gotowy pasek narzędzi: Przykład 1.

Krok dalej: JavaScript cię wyręczy

Teraz trochę zaszalejemy z pozostałymi dziewięcioma kafelkami. Istnieje bowiem jedno wspaniałe zastosowanie paska narzędzi cechujące się tym, że:

Oczywiście, mam na myśli CMS-y (i wszystkie inne RIA).

Zmodyfikujmy więc nasz pasek narzędzi w paru miejscach. Pierwsza zmiana – w samym HTML-u:

  1. <ul class="toolbar" id="toolbar1">
  2. <li class="left">-</li>
  3. <li><div class="kafelka5" onclick="" title="Pogrubienie"></div></li>
  4. <li><div class="kafelka6" onclick="" title="Kursywa"></div></li>
  5. <li><div class="kafelka7" onclick="" title="Podkreślenie"></div></li>
  6. <li><div class="kafelka8" onclick="" title="Odnośnik"></div></li>
  7. <li class="separator">-</li>
  8. <li><div class="kafelka9" onclick="" title="Kopiuj"></div></li>
  9. <li><div class="kafelka10" onclick="" title="Wytnij"></div></li>
  10. <li><div class="kafelka11" onclick="" title="Wklej"></div></li>
  11. <li class="separator">-</li>
  12. <li><div class="kafelka12" onclick="" title="Cofnij"></div></li>
  13. <li><div class="kafelka13" onclick="" title="Powtórz"></div></li>
  14. <li class="right">-</li>
  15. </ul>

Gołym okiem widać zmianę. Przyciski nie są teraz definiowane przez znacznik <a>, tylko <div>. To raczej dobry zwyczaj, w końcu odnośniki <a> mają odsyłać do innych dokumentów, a nie wywoływać JavaScript.

W powyższym kodzie, każdy <div> posiada klasę kafelka*, gdzie w miejscu gwiazdki znajduje się numer kafelki w pliku PNG. Korzystamy z tego samego obrazka, co w poprzednim przykładzie, więc pomińmy pięć pierwszych ikon i zacznijmy od kafelka5 (czyli szósta kafelka, bo jak zawsze w JavaScripcie, zaczynamy liczyć od zera). Funkcja, która kadruje kafelki wygląda tak:

  1. var tileWidht=25;
  2. var tilePrefix='kafelka';
  3. //
  4. window.onload=function()
  5. {
  6. var toolbar1=document.getElementById('toolbar1');
  7. loadTiles(toolbar1);
  8. }
  9. //
  10. function loadTiles(node)
  11. {
  12. var div=node.getElementsByTagName('div');
  13. for (var i=0;i<div.length;i++)
  14. {
  15. var tile=div[i].className.replace(tilePrefix,'')
  16. div[i].style.backgroundPosition = '-' + tile*tileWidht + 'px 0%'; //ex. "-25px 0%"
  17. //
  18. div[i].onmouseover=function ()
  19. {
  20. var tile=this.className.replace(tilePrefix,'')
  21. this.style.backgroundPosition = '-' + tile*tileWidht + 'px 100%';
  22. }
  23. div[i].onmouseout=function ()
  24. {
  25. var tile=this.className.replace(tilePrefix,'')
  26. this.style.backgroundPosition = '-' + tile*tileWidht + 'px 0%';
  27. }
  28. }
  29. }

Aby omówić powyższy kod, musiałbym wydłużyć ten artykuł o 10 akapitów, więc może nie tym razem. Ważną rzeczą jest, że funkcja loadTiles() obsługuje tylko "dwurzędowe" pliki z kafelkami, w których drugi rząd zawiera wersję ikony wyświetlaną podczas onmouseover. Szerokość kafelek reguluje zmienna tileWidht, znajdująca się w górnej części skryptu, można więc go łatwo skonfigurować do swoich potrzeb.

Nie obyło się też bez małej modyfikacji kodu CSS. Zmiany znajdziesz bez trudu, śledząc gotowy Przykład 2.

Czy możemy pójść jeszcze dalej?

Oczywiście, kafelkowanie można zautomatyzować jeszcze bardziej. Na przykład, moglibyśmy zrezygnować z drugiego rzędu kafelków i nakładać tło pod rollovery dynamicznie. W połączeniu z grafiką w formacie PNG z kanałem alpha, moglibyśmy uzyskać świetny efekt.

Należy jednak pamiętać też o wadach tej metody. Nie da się ukryć, że użytkownicy starych wersji przeglądarek nie zobaczą naszej strony tak jak należy. Po drugie, jeśli kadrujemy kafelki automatycznie za pomocą JavaScriptu tak jak w przykładzie drugim, użytkownik zobaczy je dopiero po załadowaniu się całego dokumentu (gdyż wywołaliśmy funkcję kadrującą podczas zdarzenia window.onload).

Marcin Warpechowski


Przykłady przedstawione w artykule


O autorze

Marcin Warpechowski

Marcin Warpechowski

W ciągu ostatnich pięciu lat próbował w sieci wielu rzeczy, mimo to wciąż najchętniej pracuje z kodem XHTML, CSS i JS. Współpracuje z agencją interaktywną Cookie. Moderator forum Webesteem. W wolnych chwilach studiuje ekonomię.