Przejdź do treści

Oprawa graficzna - CSS

"Duszki" CSS

W jaki sposób przyspieszyć ładowanie grafiki na stronie WWW?

Wstęp

Nie od dzisiaj wiadomo, że szybkość wczytywania strony internetowej ma bardzo duży wpływ na jej odbiór przez użytkowników. W skrajnym przypadku potencjalny czytelnik może w ogóle opuścić serwis, jeśli w rozsądnym czasie nie doczeka się na załadowanie pełnej treści. "Najcięższymi" elementami stron internetowych są wszelkiego rodzaju multimedia - grafika, animacje Flash itp. - nie należy więc przesadzać z ich liczbą, bo dużo nie zawsze znaczy lepiej. Tworząc galerię zdjęć zadbaj, aby miniatury były fizycznie pomniejszonymi grafikami, a nie tymi samymi plikami co duże zdjęcia, a jedynie zmniejszone za pomocą atrybutów HTML lub CSS. Weź pod uwagę, że użytkownik niekoniecznie będzie chciał obejrzeć powiększenia wszystkich zdjęć z galerii, a nawet jeśli, raczej nie będzie tak cierpliwy, aby czekać nawet kilka minut, na załadowanie od razu wszystkich pełnowymiarowych zdjęć.

Formaty graficzne

Kluczowe znaczenie dla zmniejszenia rozmiaru plików zdjęć, a zatem równocześnie przyspieszenie wczytywania strony, ma dobranie odpowiedniego formatu oraz stopnia kompresji. Popularne formaty internetowe oferują wbudowane algorytmy kompresji danych. W przypadku kompresji bezstratnej nie ma żadnej utraty jakości na wynikowej grafice. Kompresja stratna co prawa powoduje utratę jakości, ale jest to słabo zauważalne dla przeciętnego człowieka, a zyski są ogromne. Stopień kompresji można ustawić najczęściej podczas zapisu pliku w dowolnym, bardziej rozbudowanym programie graficznym. Naprawdę warto poeksperymentować!

BMP

Nigdy nie używaj na stronach internetowych formatu BMP (ang. bitmap), ponieważ nie zapewnia on dobrej kompresji, a więc pliki w nim zapisane są ogromne!

GIF

Do wszelkiego rodzaju ręcznie rysowanych ikon zawierających przezroczystość najczęściej używa się formatu GIF (ang. Graphics Interchange Format). Ma on wbudowany algorytm bezstratnej kompresji danych, ale potrafi zapisać tylko 256 kolorów.

JPG

Do wielokolorowych zdjęć natomiast niezrównany jest format JPG (ang. Joint Photographic Experts Group). Obsługuje kompresję stratną jednak bez przezroczystości.

PNG

Alternatywą dla formatu GIF może być PNG (ang. Portable Network Graphics), który zapewnia bezstratną kompresję danych i - w odróżnienia od GIF - wielostopniową przezroczystość, dzięki której ikony PNG nie mają poszarpanych krawędzi, nieważne na jakim kolorze tła zostaną wyświetlone. Pewną wadą PNG może być niepoprawna obsługa przezroczystości w MSIE 6, ale przeglądarka ta nie jest już tak popularna jak kiedyś.

Żądania HTTP

A co zrobić, kiedy wszystkie grafiki mamy już zapisane w odpowiednim formacie i przy optymalnie dobranym stopniu kompresji? Okazuje się, że na długość czasu wczytywania kompletnej strony WWW ma wpływ nie tylko co, ale w jaki sposób jest ładowanie. Po wybraniu adresu dowolnego współczesnego serwisu internetowego, przeglądarka zaczyna ładowanie dokumentu HTML oraz wszystkich elementów osadzonych na takiej stronie: głównie obrazków. Aby skrócić czas, przeglądarka nie ładuje osadzonych na stronie plików jeden po drugim, ale równocześnie po kilka - każdy w oddzielnym żądaniu HTTP (ang. HTTP request). Liczba jednoczesnych żądań jest jednak ograniczona, więc część plików musi poczekać na swoją kolej. Kluczem do skrócenia czasu wyczytywania elementów strony WWW jest zmniejszenie liczby żądań HTTP, które przeglądarka wysyła do serwera. Można to zrobić wyrzucając niepotrzebne pliki albo łącząc kilka plików w jeden. Korzystniej będzie np. dołączyć jeden, nawet większy plik CSS czy JS niż kilka(naście) małych pliczków. Wydawać by się mogło, że nie dotyczy to obrazków - nic bardziej błędnego. Można przecież zamiast zapisywać każdej ikonki w osobnym pliku, zapisać je wszystkie (lub większość) na jednym "arkuszu" w pojedynczym pliku graficznym. W ten sposób można zaoszczędzić nawet kilkadziesiąt żądań HTTP, co ma duży wpływ na szybkość ładowania strony zwłaszcza dla użytkowników, którzy pierwszy raz odwiedzają serwis, a więc ich przeglądarki nie mają jeszcze zapisanych w lokalnej pamięci cache żadnych obrazków ze strony. Badania wykazują, że aż 40-60% użytkowników przeciętnego serwisu może należeć do tej grupy.

Technika zapisywania wielu grafik w jednym pliku nosi nazwę "duszki" CSS (ang. CSS sprites). Nazwa ta pochodzi z czasów komputerów 8-bitowych, gdzie mianem "duszków" określało się statyczne grafiki postaci i innych obiektów występujących w grach 2D, które komputer przesuwał po ekranie. W przypadku CSS, plik graficzny z duszkami możemy sobie wyobrazić w postaci siatki z ułożonymi ikonami. Jeśli chcemy wyświetlić wybraną ikonę, nakładamy na siatkę nieprzezroczystą maskę z okienkiem w środku, które ustawiamy nad tą ikoną, na której nam zależy, jednocześnie zasłaniając pozostałe. Tym okienkiem są krawędzie elementu, pod którym wyświetlamy tło graficzne.

Siatka ikon z nałożoną maską z okienkiem w środku

Zwykle nie jest obojętne, w jaki sposób ułożymy poszczególne grafiki na arkuszu. Przedstawiony powyżej przykład ikon o identycznych wymiarach, należy do rzadkości. Dalej na przykładach dowiemy się, w jaki sposób projektować optymalne rozłożenie grafik na arkuszu z "duszkami" CSS, tak aby potem nie było problemu z ich wykorzystaniem na rzeczywistej stronie WWW. Wszystkie przykłady będą oparte o ten sam, pojedynczy plik graficzny (obramowanie zostało dodane tylko dla wskazania krawędzi arkusza - nie zawiera się w samym obrazku):

Arkusz z duszkami CSS

Pionowe menu

Najmniej problemu jest z elementami, które będą stanowić zwyczajne tło pod tekstem. Tak jest w przypadku menu pionowego, opisanego wcześniej w rozdziale Menu w CSS. Tutaj wykonamy go przy wykorzystaniu "duszków".

<ul>
<li><a href="czcionki.html">Czcionki</a></li>
<li><a href="tekst.html">Tekst</a></li>
<li><a href="tlo.html">Tło</a></li>
<li><a href="marginesy.html">Marginesy</a></li>
<li><a href="obramowanie.html">Obramowanie</a></li>
</ul>
ul, ul li {
	display: block;
	list-style: none;
	margin: 0;
	padding: 0;
	line-height: normal;
	font-size: 12px;
}

ul li {
	width: 200px;
	border-width: 1px;
	border-style: solid;
	border-color: #dfe #365 #365 #dfe;
}

ul a:link, ul a:visited {
	display: block;
	width: 169px;
	text-decoration: none;
	padding: 5px 10px 5px 20px;
	font-weight: bold;
	background: #bfb url(obrazek.gif) no-repeat -16px -25px;
	color: #365;
	border-left: 1px solid #797;}

ul a:hover {
	background-color: #797;
	background-position: -16px -49px;
	color: #eff;
}

Rezultat:

Na komentarz zasługują ujemne wartości położenia tła obrazkowego "background-position: -16px -25px". Jak wiadomo, pierwsza z wartości określa poziomą odległość obrazka tła od lewej krawędzi elementu, a druga - pionową odległość od górnej krawędzi elementu. Współrzędne są liczone względem lewego-górnego narożnika obrazka. Dodatnie współrzędne odsunęłyby zatem obrazek w prawo i w dół - zgodnie z komputerowym układem współrzędnych (zobacz: Nakładanie). My jednak musimy wykonać przesunięcie w przeciwnym kierunku, ponieważ grafika tła do naszego menu znajduje się w środku arkusza - stąd ujemne współrzędne. Przy wyznaczaniu pozycji poszczególnych "duszków", należy odmierzyć odległości od lewego-górnego narożnika całego arkusza do lewego-górnego narożnika wybranej grafiki z siatki i nadać obu wartościom - poziomej i pionowej - znak ujemny.

Poziome menu

W przypadku poziomego menu, w którym każda z zakładek może mieć inną szerokość, ważne jest, aby oba "duszki", z których składa się zakładka, były usytuowane bezpośrednio przy prawej krawędzi arkusza. Gdyby na arkuszu cokolwiek znalazło się z prawej strony lewego, wąskiego brzegu zakładki, po złożeniu mogłoby to wystawać zza pozostałej części zakładki. Szeroka, prawa część zakładki musi się znaleźć całkowicie przy prawej krawędzi arkusza z "duszkami", ponieważ tylko w ten sposób jest możliwe ustawienie tła przy prawej krawędzi zakładki (poprzez podanie poziomej pozycji jako 100%), zapewniając automatyczne dopasowanie szerokości do długość tekstu na zakładce.

ul, ul li {
	display: block;
	list-style: none;
	margin: 0;
	padding: 0;
	line-height: normal;
	font-size: 12px;
}

ul {
	float: left;
	width: 100%;
	border-bottom: 1px solid #365;
	padding-left: 20px;
}

ul li {
	float: left;
	background: url(obrazek.gif) no-repeat -240px -25px;
	margin-right: 5px;
}

ul a:link, ul a:visited {
	text-decoration: none;
	display: block;
	font-weight: bold;
	background: url(obrazek.gif) no-repeat 100% 0;
	color: #365;
	padding: 5px 15px 5px 5px;
	margin-left: 10px;
}

ul a:hover {
	color: #032;
}

Rezultat:


Ikony

W przypadku ikon, należy zwrócić uwagę, czy na stronie występują one z lewej bądź z prawej strony tekstu. Jeśli z lewej, trzeba zadbać, aby żadna grafika nie znalazła się na arkuszu po ich prawej stronie - najłatwiej to zapewnić poprzez ustawienie ikony przy prawej krawędzi arkusza z "duszkami". Dla ikon występujących po prawej stronie tekstu, mamy sytuację odwrotną - najwygodniej wstawiać je bezpośrednio przy lewej krawędzi arkusza.

div {
	padding-left: 20px;
	font: bold 16px /17px Arial, Helvetica, sans-serif;
	color: #d80;
	background: url(obrazek.gif) no-repeat -234px -50px;
}
Ulubione

a:link, a:visited {
	padding-right: 20px;
	font: bold 16px /17px Arial, Helvetica, sans-serif;
	color: #08d;
	background: url(obrazek.gif) no-repeat 55px 1px;
	text-decoration: none;
	border: 0;
}

a:visited {
	color: #0cf;
}

Więcej

Listy

Aby prawidłowo ostylizować wyróżniki obrazkowe listy wypunktowanej, należy zadbać, aby na arkuszu z "duszkami" nie było żadnej grafiki z prawej strony ani poniżej markera graficznego listy. W przeciwnym przypadku ta dodatkowa grafika ukazałaby się pod tekstem punktów wykazu albo dostalibyśmy coś na kształt zdublowanego wyróżnika obrazkowego - jeden pod drugim. Kolejne grafiki wyróżników trzeba ustawiać przy prawej krawędzi arkusza, posuwając się dalej w lewo do dołu. Warto nadmienić, że w celu oszczędności miejsca na arkuszu, nic nie stoi na przeszkodzie, aby inne ikony wstawiać z lewej powyżej skośnej linii, utworzonej na arkuszu przez punkty wykazu.

ul, ul li {
	display: block;
	list-style: none;
	margin: 0;
	padding: 0;
	line-height: 14px;
	font-size: 12px;
}

ul li {
	margin: 2px 0;
	padding-left: 16px;
	background: url(obrazek.gif) no-repeat -240px -65px;
}
  • Czcionki
  • Tekst
  • Tło
  • Marginesy
  • Obramowanie

ul, ul li {
	display: block;
	list-style: none;
	margin: 0;
	padding: 0;
	line-height: 14px;
	font-size: 12px;
}

ul li {
	margin: 2px 0;
	padding-left: 16px;
	background: url(obrazek.gif) no-repeat -224px -81px;
}
  • Czcionki
  • Tekst
  • Tło
  • Marginesy
  • Obramowanie

Wskazówki

Czy wszystko powinniśmy umieszczać na arkuszach z "duszkami" CSS? W żadnym razie nie powinny być tam umieszczane ilustracje wstawiane do treści. Stanowią one uzupełnienie artykułów redakcyjnych i powinny być osadzane za pomocą standardowego znacznika IMG. Technicznie niewykonalne jest wstawienie na siatkę z "duszkami" wzorka, który następnie zostanie powielony, tworząc tło graficzne. Tutaj jedynym możliwym rozwiązaniem jest umieszczenie grafiki w osobnym pliku, lecz zwykle takich przypadków nie jest wiele. Jeżeli natomiast chodzi o tła graficzne powielane tylko w jednym kierunku - poziomo lub pionowo - możemy je zgrupować na dwóch osobnych arkuszach z "duszkami": grafiki powielane w poziomie na wąskim, ale wysokim arkuszu (jedna pod drugą), natomiast powielane w pionie - na niskim, ale szerokim (jedna obok drugiej). W ten sposób, nie licząc tła graficznego powielanego w obu kierunkach, każdy serwis można zbudować w oparciu o trzy arkusze z "duszkami" CSS: zwykły, poziomy i pionowy. Ponadto na jednym arkuszu nie warto mieszać ręcznie rysowanych ikon (które zwykle zapisujemy w formacie GIF lub PNG) z wielokolorowymi zdjęciami (zwykle zapisywane w JPG), ponieważ wtedy albo rozmiar pliku niewspółmiernie wzrośnie albo znacznie stracimy na jakości. Najczęściej jednak, chyba jedynym elementem oprawy graficznej, który wymaga zapisania w formacie JPG, może być tzw. top serwisu, który w ostateczności można zapisać osobno.

Oczywiście może się tak zdarzyć, że niektóre z "duszków" dla poprawnego wyświetlenia ich na stronie, będą musiały być ułożone przy górnej lub dolej krawędzi arkusza. Będzie to miało miejsce np. w przypadku wierzchu ramki, której wysokość na stronie dopasowuje się do zawartości - zwykle musimy ją umieścić przy dolnym brzegu arkusza. Spód takiej ramki umieszcza się natomiast przy górnym brzegu.

Jak można zauważyć nawet na przygotowanym przykładowym arkuszu z "duszkami", bardzo trudno jest upakować na nim grafiki w taki sposób, aby nie zostawić żadnych wolnych miejsc. Nie jest to jednak aż taki problem, jakby się mogło wydawać, ponieważ przyjęty algorytm kompresji plików graficznych powoduje, że wzrost rozmiaru pliku, mimo pustych przestrzeni, nie jest duży. Dla przykładu, jednokolorowy plik GIF o rozmiarach 1x1 piksel jest tylko ok. 50 razy "lżejszy" niż o rozdzielczości 1000x1000, choć ten drugi obrazek zapisuje aż 1 mln razy więcej pikseli!

Podsumowanie

Jak przekonaliśmy się na przykładach, technika zwana "duszkami" CSS (CSS sprites) ma kilka zalet:

  • Wydatnie przyspiesza ładowanie strony
  • Doskonale wpisuje się w dobrą praktykę tworzenia całej oprawy graficznej serwisu za pomocą grafik wstawianych w tle elementów strony (zobacz: Zamiennik obrazkowy)
  • Zbiera całą oprawę graficzną serwisu w pojedynczym pliku, dzięki czemu bardzo łatwo można przygotować inną wersję kolorystyczną oprawy graficznej

Nie ma się co jednak oszukiwać, "duszki" CSS nie są rozwiązaniem w każdej sytuacji idealnym:

  • Projektowanie rozłożenia "duszków" na arkuszu jest bardziej skompilowane niż zapisanie ich w osobnych plikach
  • Każdorazowe dokładne wyznaczanie pozycji tła dla poszczególnych elementów strony może być bardziej uciążliwe podczas tworzenia arkusza CSS
  • Rozbudowa serwisu o nowe ikony, gdy arkusz został już wcześniej zaprojektowany, może nie być prosta; w niektórych przypadkach może to wymagać nawet ponownego wyznaczania pozycji wielu istniejących wcześniej "duszków"

O tym czy stosować tę technikę, dobrze jest zdecydować mając do zaprojektowania konkretny serwis. Zyski na pewno są znaczące w przypadku dużej liczby niewielkich elementów oprawy graficznej. Dodatkowo za stosowaniem "duszków" CSS może przemawiać fakt, że korzysta z nich większość najpopularniejszych portali internetowych w Polsce i na świecie.

Komentarze

Zobacz więcej komentarzy

Facebook