Stworzenie strony internetowej, która poprawnie wyświetli się w wielu rozdzielczościach, to zawsze spore wyzwanie. Jednym z jego elementów jest poprawne skalowanie grafik, aby dostosować je do dostępnej w danym urządzeniu liczby pikseli. W tym artykule omówię większość popularnych metod na radzenie sobie z grafikami na responsywnej stronie internetowej.

Jak zapewne większość z Was wie, wszelkiego rodzaju grafiki na stronę internetową wstawiamy korzystając z tagu img. Jeśli nie ustalimy żadnych rozmiarów za pomocą CSS lub atrybutów widthheight, grafika zostanie zamieszczona w swoich naturalnych wymiarach. Ustawiając tylko szerokość lub wysokość sprawimy, że ta druga wartość zostanie dopasowana tak, aby obrazek zachował swoje proporcje. Tak więc aby upewnić się, że grafika będzie zawsze dopasowana do elementu, w którym się znajduje, wystarczy ustawić jej szerokość na 100%.

Jest to jednak rozwiązanie dalekie od ideału, ponieważ spowoduje rozciągnięcie obrazka, jeśli zostanie on wstawiony do elementu od niego większego. Tutaj z pomocą przychodzi polecenie max-width, które ustawia maksymalną szerokość elementu. Jeśli ustawimy ją na 100% będzie to oznaczało, że maksymalna szerokość obrazka nie może przekroczyć szerokości rodzica.  Dodatkowo, aby mieć całkowitą pewność, że obrazek zostanie poprawnie przeskalowany, należy dodać height: auto;. To w wypadku, gdy obrazek ma zapisaną w kodzie wielkość, której nie możemy zmienić (obrazki wstawiane przed edytor WordPressa na przykład, mają wymiary obrazków zapisane w atrybutach widthheight).

img {
    max-width: 100%;
    height: auto;
}

Grafika w tle

Innym sposobem na umieszczanie grafik na stronach jest wstawienie ich jako tło elementu. Również w tym przypadku, domyślnym zachowaniem jest umieszczanie obrazka w jego domyślnej wielkości. Jeśli element jest mniejszy, tło zostanie przycięte do jego wielkości, zachowując swój rozmiar. Metodą na zmianę tego zachowania jest zastosowanie polecenia background-size. Za jego pomocą możemy dokładnie określić wymiary tła. poniżej kilka przykładów:

  • background-size: 300px 300px; – obrazek tła zostanie przeskalowany do dokładnie takich wymiarów, jakie podaliśmy; jeśli zastąpimy jedną z wartości słowem auto, obrazek zostanie przeskalowany z zachowaniem jego proporcji; oczywiście pierwsza wartość to szerokość, a druga to wysokość;
  • background-size: 75% 50%; – jeśli wartości wyrazimy w procentach, obrazek zostanie przeskalowany relatywnie do elementu, którego tło stanowi, jeśli zatem ustawiamy tło elementu <div>, którego wymiary to 300×150 pikseli, to tło będzie miało wielkość 150×37 pikseli; tutaj również ma zastosowanie słowo auto i działa identycznie jak w przykładzie powyżej;
  • background-size: contain; – za pomocą tego ustawienia możemy dopasować wielkość obrazka do elementu w taki sposób, aby był tak duży jak to tylko możliwe, zachowując jednocześnie swoje proporcje;
  • background-size: cover; – w tym przypadku, obrazek dopasowywany jest do elementu tak, aby zawsze pokrywać go w całości; obrazek podczas skalowania zachowuje swoje proporcje;

Wartością domyślną dla background-size jest auto, które zachowuje oryginalne wymiary grafiki. Na poniższym obrazku zobrazowano wszystkie zachowanie tła w opisanych wyżej przypadkach:

rozklad-tla-background-size-css-cover-contain

Zachowanie tła w zależności od użytej wartości CSS, zdjęcie © Eugenio Marongiu, Fotolia

Wykorzystując powyższą wiedzę możemy przeskalować dowolny obrazek do szerokości dostępnej na urządzeniu, na którym jest aktualnie wyświetlany.

Omówiliśmy podstawy, teraz przejdźmy do bardziej wymagających zagadnień.

Rozdzielczość ekranu i stosunek pikseli

Producenci telefonów, tabletów, a ostatnio także laptopów i monitorów do komputerów stacjonarnych cały czas zwiększają nam rozdzielczość, jaką obsługują ich urządzenia. Dzięki temu możemy cieszyć się coraz lepszą jakością wyświetlanych przez nie zawartości. Stworzyło to też pewien problem. Jeśli upchniemy rozdzielczość 1440×2560 pikseli na 5 calowym ekranie, nie będzie nic widać. Stąd też przeglądarki automatycznie powiększają wszystkie elementy strony o ustalony dla danego urządzenia stosunek pikseli. Stosunek ten informuje nas, ile realnych pikseli zostało użytych do wyświetlenia jednego piksela wirtualnego. Na przykład: ekran iPhone’a 5s ma rozdzielczość 640×1136 px i stosunek pikseli 2 więc dla przeglądarki to 320×568 wirtualnych pikseli; ekran Samsunga Galaxy Note 4 ma rozdzielczość 1440×2560 px i stosunek pikseli 4 więc dla przeglądarki to 360×640 wirtualne piksele.

Na tej samej zasadzie skalowane są też grafiki. Dlatego należy pamiętać, że mimo, iż na ekranie iPhone’a 5s wyświetla się grafika, która ma teoretycznie 568 pikseli szerokości, tak naprawdę ma ich 2 razy więcej. Jeśli na urządzeniu ze stosunkiem pikseli 1 wyświetlamy grafikę o szerokości 500 pikseli, to jeśli chcemy, aby była ona tak samo ostra na urządzeniu ze stosunkiem pikseli 4, powinniśmy wyświetlić ją w szerokości 2000 pikseli. Aby sprawdzić jaki stosunek pikseli ma dane urządzenie, wystarczy uruchomić na nim poniższy kod w formie pliku HTML:

<!DOCTYPE html>
<html lang="pl">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">

        <title>Stosunek pikseli</title>
    </head>
    <body>
        <script>
            document.write(window.devicePixelRatio);
        </script>
    </body>
</html>

Pamiętając o wymiarach grafiki pamiętajmy również o jej wadze. Dlatego podczas zapisywania plików do internetu powinniście zmierzać do osiągnięcia idealnego kompromisu pomiędzy wielkością pliku a jego jakością. Zapisywanie każdego pliku JPG w jakości 100% to zdecydowanie nie jest dobry pomysł. Niekoniecznie dobrym pomysłem jest też serwowanie grafik dokładnie w takiej rozdzielczości, jaką obsługuje urządzenie.  Miejcie na uwadze nie tylko pakiety internetowe ludzi odwiedzających Wasze strony, ale przede wszystkim to, że wbrew reklamom operatorów, w Polsce zasięg LTE nie jest wszędzie dostępny. A strona ładująca się w nieskończoność skutecznie zniechęca do jej eksploracji. Jeśli wasze oko jest ogromnie wrażliwe na jakość i nie możecie stwierdzić, do którego momentu utrata detali jest jeszcze akceptowalna, postarajcie się znaleźć jedną, czy też kilka osób, które na co dzień nie zajmują się grafiką i sprawdźcie, kiedy zaczną dostrzegać różnice. Testowanie swojej pracy na grupie zbliżonej do odbiorców docelowych da zawsze pozytywne rezultaty.

Istnieją oczywiście sytuacje, w których o kompromisie nie może być mowy. Co zrobić, by zaoszczędzić transfer i nie serwować grafik w wysokiej rozdzielczości urządzeniu, które nie da rady ich wyświetlić? Z pomocą przychodzą media queries:

.header {
    width: 100%;
    height: 500px;
    background: url('1920x500.jpg') no-repeat center;
    background-size: cover;
}

@media (max-width: 640px) {
    .header {
        background-image: url('640x500.jpg');
    }
}

@media only screen and (max-width: 640px) and (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2) {
    .header {
        background-image: url('1920x500.jpg');
    }
}

W powyższym przykładzie, domyślnie wyświetlamy tło o rozmiarach 1920×500 pikseli. Dla komórek, redukujemy rozmiar do 640×500 pikseli po czym dla komórek o stosunku pikseli 2 i więcej, ponownie wracamy do wersji 1920×500 pikseli.

Nowe funkcje przeglądarek

Czy nie byłoby świetnie, gdyby to przeglądarka sama decydowała o tym, jaki obrazek wyświetlić, biorąc pod uwagę dostępną wielkość ekranu i stosunek pikseli? Uwolniłoby to nas od pisania media query na każdą okazję. Okazuje się, że taka funkcja już istnieje! Spójrzcie na kod poniżej:

<img src="1024x768.jpg" srcset="320x240.jpg 320w, 640x480.jpg 640w, 1024x768.jpg 1024w" alt="Przykład">

Nowością jest tutaj atrybut srcset, w którym podajemy kilka wariantów tego samego obrazka (w tych samych proporcjach, ale o różnych rozmiarach) i informujemy przeglądarkę, jaką podany obrazek ma szerokość. Przeglądarka sama wybierze ten najwłaściwszy i go wyświetli. Jak podejmuje decyzję? Przyjmijmy, że jest ona uruchomiona na urządzeniu o szerokości 320 pikseli i stosunku pikseli 1. Dzieli więc wszystkie podane szerokości przez 320 i wyświetla ten obrazek, przy którym wynik dzielenia był najbliżej jedynki. Jeśli zaś podobne urządzenie będzie miało szerokość 320 pikseli i stosunek pikseli 2, wynik dzielenia będzie musiał być jak najbliżej dwójki. Przeglądarka zawsze zakłada domyślnie, że będziemy chcieli wyświetlić obrazek na całej szerokości ekranu. Jeśli na stronie mamy na przykład sidebar i chcemy zmienić to zachowanie, używamy atrybutu sizes, który pozwala określić, podobnie do media query, jaką część obrazu zajmuje obrazek w danym momencie. Modyfikujemy wtedy nasz kod w sposób następujący:

<img src="1024x768.jpg" srcset="320x240.jpg 320w, 640x480.jpg 640w, 1024x768.jpg 1024w" sizes="(min-width: 800px) 70vw, 100vw" alt="Przykład">

Co dokładnie oznacza ta składnia? Jeśli strona ma minimum 800 pikseli szerokości, obrazek będzie zajmował około 70% ekranu (jednostka vw oznacza view width 1vw to 1% szerokości ekranu)., w pozostałych przypadkach, będzie zajmował 100% ekranu. Dzięki temu, przeglądarka podejmie lepszą decyzję odnośnie tego, jaki obrazek powinna wybrać.

Możemy też przypisać „na sztywno” jaki obrazek przy jakiej proporcji pikseli ma wybrać przeglądarka, wtedy kod wygląda następująco:

<img src="1024x768.jpg" srcset="320x240.jpg 1x, 640x480.jpg 2x, 1024x768.jpg 3x" alt="Przykład">

Zwróćcie uwagę na atrybut src w trzech powyższych przykładach. Nie jest on wymagany, ale zapewnia prawidłowe wyświetlenie obrazka w wypadku, gdy atrybut srcset nie jest wspierany. W momencie pisania tego artykułu, wsparcie przeglądarek dla tej funkcji było dość dobre. Możecie je sprawdzić na stronie Can I use. Poprawną obsługę dla przeglądarek niewspierających tej funkcji zapewnia biblioteka o nazwie Picturefill. Jej użycie jest bardzo proste i ogranicza się jedynie do podlinkowania pliku JavaScript do strony.

Bezpośrednio w arkuszu CSS również możemy wskazać kilka wersji obrazków dla różnych proporcji pikseli. Osiągamy to za pomocą funkcji image-set(), która przyjmuje wartość podobną do atrybutu srcset. Spójrzcie na kod poniżej:

.header {
    background-image: url('1024x768.jpg');
    background-image: -webkit-image-set(
        url('320x240.jpg') 1x,
        url('640x480.jpg') 2x,
        url('1024x768.jpg') 3x
    );
    background-image: image-set(
        url('320x240.jpg') 1x,
        url('640x480.jpg') 2x,
        url('1024x768.jpg') 3x
    );
}

Najpierw podajemy tło domyślne dla przeglądarek, które nie wspierają funkcji image-set(), następnie kod z prefiksem dla silnika Webkit oraz kod dla reszty przeglądarek. Póki co, wsparcie dla tego rozwiązania oferuje jedynie silnik Webkit, ale niektórym z Was może to wystarczyć, ponieważ urządzeń mobilnych nie używających Webkita jest bardzo mało.

Unikajcie rastrów

Ponieważ wszelkiego rodzaju grafiki rastrowe mają problemy ze skalowaniem, należy – tam gdzie to możliwe – zrezygnować z ich używania. Gdzie tylko się da używajcie formatu SVG, który idealnie nada się do logo. Do ikon z kolei świetnie sprawdzą się fonty. Oczywiście grafik w formacie PNG czy JPG całkowicie nie wyeliminujecie, ale z pewnością da się je ograniczyć.

Podsumowując

Mam nadzieję, że dowiedzieliście się z tego artykułu co nieco o umieszczaniu obrazków na responsywnej stronie internetowej. Temat nie jest z pewnością w stu procentach zakończony, ale posiadając powyższą wiedzę, możecie bez problemu przystąpić do projektowania bardziej wydajnej strony internetowej, która bez problemu wyświetli właściwe obrazki na wszystkich urządzeniach. Jeśli macie jakieś pytania oczywiście piszcie w komentarzach.