Moduł 6 - Zajęcia 1 - Responsywność
1.1 Strony responsywne
Za pomocą jakiego urządzenia ludzie korzystają z Internetu? Nawet dla pojedynczego człowieka nie ma jednoznacznej odpowiedzi. Powiedzmy, że w podróży używamy najczęściej smartphona, a w biurze - komputera stacjonarnego. Jak można powiedzieć o większości ludzi? Procent użytkowników urządzeń mobilnych rośnie, jednak także komputery stacjonarne utrzymują popularność. Dla developera oznacza to jedno: konieczność tworzenia stron internetowych, które będą wyglądać równie dobrze na różnych urządzenia. Dla tego celu powstał design responsywny.
1.2 Design adaptacyjny i responsywny
Kiedyś design stron internetowych był tworzony ze ściśle określoną szerokością. Jeśli strona była obliczona na szerokość 960 pikseli, to 960 pikseli zostawało niezależnie od tego, na jakim ekranie była otwierana: czy to na dużym, czy małym.
Współczesne strony internetowe powinny jednakowo dobrze wyglądać na każdym ekranie: telewizorze, komputerze stacjonarnym, notebooku, tablecie, smartfonie czy nawet na lodówce.
Nowoczesne strony internetowe wykorzystują nowe podejścia przy projektowaniu i tworzeniu:
- Adaptacyjność (adaptive)
- Responsywność (responsive)
Techniki układu adaptacyjnego i responsywnego odróżniają się:
- tym, jak ustawiana jest szerokość treści
- ilością wariantów wyświetlania strony przewidzianych przez design
Responsywna (responsive) strona internetowa posiada kilka opcji wyświetlania, przejścia między nimi są gładkie, elementy, a kontenery są rozciągnięte jako guma. Podczas zmiany rozmiaru viewportu bloki są lekko ściskane lub rozciągane, a gdy nadchodzi punkt złamania, zmieniają swoją lokalizację, aby optymalnie zająć całą wolną przestrzeń w poziomie
Adaptacyjna (adaptive) strona internetowa posiada kilka wariantów wyświetlania. W przeciwieństwie do designu responsywnego — to dosłownie różne stany. Design zmienia się gwałtownie w ściśle określony punkach przełamania i nie rozciąga się między nimi.
Rozmiar obszaru wyświetlania, w którym cały układ lub jego poszczególne części zmieniają swoje style (tj. zmiana designu) nazywa się punktem przełamania (breakpoint).
Jak to wygląda w praktyce?
1.3 Viewport (rzadko: rzutnia)
Viewport (rzadko: rzutnia) — to widoczny, prostokątny obszar strony internetowej, który nie zawiera paska adresu, panelu zakładek i innych elementów serwisowych przeglądarki.
Przeglądarki mobilne wyświetlają stronę internetową w wirtualnym viewporcie (layout viewport). Szerokość wirtualnego viewportu zależy od producenta urządzenia. Najczęściej spotykana wartość szerokości wirtualnego viewportu to domyślnie 980px
Fizyczny viewport (visual viewport) — to wielkość, która wynosi tyle, co fizyczna szerokość ekranu urządzenia. W urządzeniach mobilnych wielkość fizycznego viewportu domyślnie nie zgadza się z wirtualnym. Viewport wirtualny jest szerszy od realnego ekranu urządzenia.
Na tym polega cały problem.
Przeglądarka mobilna otwiera stronę internetową i pyta się urządzania, jaką posiada ono szerokość viewportu. Domyślnie przeglądarka otrzymuje w odpowiedzi wielkość wirtualnego viewportu (980px), a nie fizycznego. W efekcie zawartość strony wyświetla się na fizycznym ekranie nieprawidłowo.
Adaptacyjne zasady CSS, koncentrujące się na urządzeniach mobilnych, po prostu nie będą używane, albo będą przekraczane w przeglądarce mobilnej. Na przykład, otwierając stronę internetową na ekranie o szerokości 400px, zastosowane zostaną adaptacyjne zasady CSS, obliczone na szerokość viewportu, na przykład 800px. Przez to zamienione zostaną style mobilne, i zobaczymy strony dla tabletów, chociaż otwieraliśmy stronę internetową na telefonie.
1.4 Meta tag viewport
Strony, adaptowane dla przeglądania na różnych urządzeniach, powinny posiadać w rozdziale <head> meta tag viewport. Powiadamia on przeglądarkę, w jaki sposób należy kontrolowac rozmiary i skalę viewportu.
<head>
<!-- Inne meta tagi -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Meta tag viewport ważny dla stron adaptacyjnych</title>
</head>
- width=device-width — określna szerokość viewport (width), która dorównuje fizycznej szerokości ekranu urządzenia (device-width).
- initial-scale=1.0 — określa stosunek (skalę) 1:1 pomiędzy pikselami CSS i pikselami fizycznymi urządzenia.
2.1 Zapytania Media
Zapytania Media — to instrument, który umożliwia tworzenie współczesnych adaptacyjnych stron internetowych, które tak samo dobrze wyglądają na dowolnym ekranie: komputerze stacjonarnym i smartphonie.
Praca z zapytaniami media to tak naprawdę zastosowanie tej czy innej zasady CSS. Wybór i wykorzystanie określonej zasady CSS zależy od takich czynników, jak:
- wielkość okna przeglądarki (viewportu)
- ustawienia przeglądarki
- możliwości urządzenia
Algorytm zastosowania stylów jest następujący:
- Developer opisuje zestaw zapytań media i zasad CSS do nich stosowanych.
- Przeglądarka śledzi zmianę rozmiaru viewportu.
- Przeglądarka stosuje zasady CSS z zapytań media, które pasują do aktualnego rozmiaru viewportu.
Można powiedzieć, że zapytania media to instrukcje, które można opisać w następujący sposób: „chcę, aby gdy strona zostanie otwarta w szerokości X, kolor tekstu był czerwony, a przy otwarciu w szerokości Y - zielony". Oprócz szerokości viewportu możemy się skupić na wielu innych kryteriach. Może to być rozdzielczość ekranu, orientacja urządzenia, ustawienia systemu operacyjnego itp.
2.2 Budowa zapytania media (media queries)
Zapytanie media jest tworzone za pomocą polecenia @media, za którym może się znajdować:
- typ urządzenia (media-type)
- typ funkcji media (media-feature)
Typ media i funkcja media to wyrażenia, które sprawdzają charakterystyki urządzenia (na przykład - szerokość viewportu).
@media media-type and (media-feature) {
/*
* Zestaw zasad CSS, jakie należy zastosować,
* jeśli warunek sprawdzenia typu media i funkcji są prawdziwe
}
Typ media i funkcja media to logiczne wyrażenia, które zwracają prawdę (poprawnie) lub fałsz (niepoprawnie). Na przykład, jeśli chcesz, aby tło <body> było pomarańczowe przy szerokości viewportu 900px lub większej, należy napisać następujące zapytanie media.
@media screen and (min-width: 900px) {
body {
background-color: orange;
}
}
W języku ludzkim można to odczytać w następujący sposób: „jeśli strona jest wyświetlana na ekranie, której szerokość wynosi co najmniej 900 pikseli, musisz zastosować określoną zasadę CSS".
2.3 Funkcja min-width
Bardzo często w zapytaniu media należy zapisać warunek sprawdzania szerokości viewportu przeglądarki. Funkcja min-width określa minimalną szerokość widocznego obszaru. W przypadku, gdy ekran odpowiada wartości w min-width, stosowane będą zawarte w zapytaniu zasady CSS.
/* Poniższe reguły CSS są stosowane, jeśli szerokość viewport jest większa lub równa 800px */
@media (min-width: 800px) {
body {
background-color: orange;
}
}
Jeśli wyobrażasz sobie szerokość widocznego obszaru jako linię prostą od 0 do nieskończoności, zasada media z funkcją min-width oznacza interwał, na którym należy zastosować style.
Na powyższym zdjęciu 800px jest breakpointem (punktem przełamania), to znaczy tym rozmiarem widocznego obszaru, w którym cały układ lub poszczególne części zmieniają swoje style, projekt strony zmienia się.
2.4 Funkcja max-width
Funkcja media max-width oznacza maksymalną szerokość viewportu, do jakiej będą stosowane zawarte w niej reguły CSS.
/* Reguły CSS są stosowane, jeśli szerokość viewport jest mniejsza albo równa się 600px */
@media (max-width: 600px) {
body {
background-color: green;
}
}
Jeśli wyobrażasz sobie szerokość widocznego obszaru jako linię prostą od 0 do nieskończoności, zasada media z funkcją max-width oznacza interwał, na którym należy zastosować style.
2.4 Wielokrotne zapytania media
Media queries (zapytań media) może być tyle, ile chcesz. Tak naprawdę liczba punktów przełamania zależy od projektu. Przeglądarka sprawdzi warunki wykonania każdego media query i użyje odpowiednich stylów.
body {
background-color: white;
}
/* Ma zastosowanie, jesli szerokość viewport jest poniżej 600px */
@media (max-width: 600px) {
body {
background-color: green;
}
}
/* Ma zastosowanie, jesli szerokość viewport jest powyżej 800px */
@media (min-width: 800px) {
body {
background-color: orange;
}
}
Gdy mamy taki kod, dla szerokości viewportu:
- do 600 pikseli tło będzie miało zielony kolor
- powyżej 800 pikseli — pomarańczowy
W zakresie od 601px do 799px - kolor tła będzie biały. Tło zaakceptuje wartości domyślnie wskazane, ponieważ żadne zapytanie media nie będzie pasować.
2.5 Nadpisywanie stylów
Przeglądarka może jednocześnie zastosować więcej niż jedno zapytanie media, jeśli spełnione są warunki funkcji media. Zapytania o media nie zwiększają specyfiki zawartych w nich selektorów, ale kolejność reguł nadal ma znaczenie. Oznacza to, że reguły zawarte w żądaniach multimediów uczestniczą w standardowym kaskadowaniu podczas tworzenia ostatecznych stylów elementu.
/* Styl bazowy */
body {
background-color: #fff;
}
/* Przy 900px i więcej zamieniamy kolor tła */
@media (min-width: 900px) {
body {
background-color: #388e3c;
}
}
2.6 Typy mediów (media types)
Typ mediów służy do opisania typu urządzeń, na których można wyświetlić stronę internetową. Ogólnie rzecz biorąc, wszystkie nowoczesne przeglądarki obsługują trzy typy
1. Wartość print umożliwia zdefiniowanie stylów, które zostaną zastosowane przy wysyłaniu do druku. Druk można wykonać na drukarce fizycznej lub wirtualnie. W tym drugim przypadku mamy na myśli urządzenia przeznaczone do odtwarzania wersji drukowanej, np. przeglądarkę internetową wyświetlającą dokument w trybie „Podgląd".
@media print {
body {
color: green;
}
}
2. Wartość screen definiuje style, które będą stosowane tylko do urządzeń z fizycznym ekranem: smartfony, tablety, monitory, telewizory itp. Oznacza to wszystko, co nie jest objęte wartością print. Wartość screen jest używana bardzo często, ponieważ wiele rodzajów mediów to urządzenia z ekranami.
@media screen and (min-width: 400px) { /* ... */ }
Można nie określać osobno typu mediów screen, jeśli:
- Style są pisane tylko dla ekranów (nie ma oddzielnych stylów do druku)
- Style są zgodne ze stylami druku.
3. Jeśli nie określono typu nośnika, zostanie użyta wartość domyślna all. Oznacza ono dowolne urządzenie.
@media (min-width: 400px) { /* ... */ }
Warunek zapytania media może być złożony lub prosty. Wszystko zależy od tego, czego wymaga sytuacja. W większości przypadków wystarczy określić typ nośnika urządzenia (najczęściej screen) i sprawdzić szerokość viewportu.
3.1 Operatory logiczne
Przyjrzeliśmy się, jak napisać warunek stylu przed i po punkcie przełomu. Powiedzmy, że chcemy opisać przedział od 600px do 900pxlub pogrupować reguły z tymi samymi stylami przed 600 pikseli i po 900 pikseli. Jak stworzyć zapytanie medialne o style, które zostaną zastosowane w zielonej przestrzeni?
Zapytania media obsługują operatory logiczne and, or, not.
Dzięki operatorom logicznym możesz łączyć warunki żądania zapytań media.
- Operator logiczny and (i) — wymusza spełnienie wszystkich warunków, aby stwierdzenie było prawdziwe.
- Logiczne or (lub) — zakłada spełnienie co najmniej jednego warunku ze zbioru, aby stwierdzenie było prawdziwe.
- Logiczne not (NIE) — implikuje inwersję, to znaczy stwierdzenie będzie prawdziwe w odwrotności: gdy warunek NIE zostanie spełniony.
Jeśli nie określono żadnego operatora, używana jest wartość domyślna — only.
@media only|not media-type ****only|and|not ****(media-feature) {
/*
Zestaw reguł CSS do zastosowania w dokumencie,
jeśli warunek sprawdzenia typu media i wyrażenia jest prawdziwy
*/
}
3.2 Operator and
Operator and (dosłownie "i") jest stosowany:
- pomiędzy typem nośnika a zapytaniem media,
- dla łączenia kilku funkcji media ze sprawdzaniem wartości — to znaczy definiowaniem odstępu między dwoma punktami przełamania.
W praktyce operator ten jest używany najczęściej.
@media screen and (min-width: 400px) and (max-width: 800px) {
body {
background-color: red;
}
}
Takie zapytanie media zostanie zrealizowane tylko wtedy, gdy zostaną spełnione dwa warunki:
- Strona internetowa jest otwarta na ekranie.
- Szerokość viewportu mieści się w zakresie 400px do 800px.
3.3 Operator or
Operator or (dosłownie "LUB") pozwala określić zestaw wyrażeń, przy spełnieniu chociaż jednego z których zostanie wykonane zapytanie media. Powiedzmy, że musisz zastosować te same style w zakresie do 600px lub ponad 900px. Operator logiczny lub w kodzie jest zapisywany jako przecinek (,)
@media screen and (max-width: 600px), (min-width: 900px) {
body {
background-color: orange;
}
}
Widzimy, że jest to po prostu wyliczenie zbioru zapytań media, dla których należy zastosować style. Można je zapisać jako dwa różne żądania multimediów. Jednak w takim przypadku kod stylu zostanie zduplikowany.
@media (max-width: 600px) {
body {
background-color: orange;
}
}
@media (min-width: 900px) {
body {
background-color: orange;
}
}
Istnieje sekret, który pomoże ci poprawnie odczytać przedziały wartości: max-width zamieniamy na słowo "DO" min-width — na słowo "OD"
Zatem powyższy przykład zapytania o media można odczytać jako: — w przedziale do 600px — w przedziale od 900px
3.4 Operator not
Operator not (dosłownie "NIE") umożliwia na wykonanie zaprzeczenia, czyli anulowanie zapytania media. Słowo kluczowe not jest dodawane na początku zapytania media i dotyczy całego żądania. Jest używane niezwykle rzadko. Zapiszmy warunek, w którym style powinny mieć zastosowanie wszędzie z wyjątkiem wydruku.
@media not print {
/* ... */
}
Przy wykorzystaniu operatora not obowiązkowo trzeba wskazać typ nośnika. Jeśli nie określisz typu nośnika, zostanie on ustawiony na wartość domyślną all. W ten sposób pojawi się wyrażenie not all, które dosłownie będzie rozumiane jako „nie dotyczy wszystkich nośników", a zapytanie media nigdy nie zostanie wykonane.
/* Nigdy nie jest wykonywane */
@media not (max-width: 500px) {
/* ... */
}
Kolejne zapytanie media zostanie zrealizowane tylko wtedy, gdy strona zostanie otwarta na urządzeniu z ekranem, a szerokość widoku będzie większa 500px.
@media not screen and (max-width: 500px) {
body {
background-color: tomato;
}
}
Zwróć uwagę! W powyższym przykładzie operator logiczny not dotyczy obu warunków w wyrażeniu screen and (max-width: 500px). Jest to cecha składni, o której należy pamiętać.
W tym przypadku, dla ułatwienia odczytania kodu, zamiast negacji max-width, prościej jest po prostu zastosować min-width.
@media (min-width: 500px) {
body {
background-color: tomato;
}
}
4.1 Podejście "Mobile First"
Projektowanie nowoczesnych stron internetowych jest zorientowane przede wszystkim na urządzenia mobilne.
Podejście Mobile First polega na tym, że najpierw powstaje projekt wersji mobilnej, potem wersji na tablety, a na końcu wersji desktopowej (webowej) - od mniejszej do większej.
Zalety podejścia Mobile First.
- Jedna strona internetowa — tylko jeden projekt dla wszystkich urządzeń. Zmniejsza liczbę wymaganych programistów.
- Wygoda interfejsu — użytkownicy na samym początku otrzymują najistotniejsze informacje.
- Szybkość ładowania — ilość pobieranych i wyświetlanych na urządzeniach mobilnych danych może być mniejsza. Dzięki temu strona może ładować się szybciej.
- Rankingi wyszukiwarek — wyszukiwarki, takie jak Google, priorytetowo traktują witryny zoptymalizowane pod kątem urządzeń mobilnych.
4.2 Implementacja
Technicznie implementacja jest dość prosta:
- style dla urządzeń mobilnych — to domyślne style poza zapytaniami media.
- dla każdego punktu przełamań dodawane jest zapytanie o media, w którym wcześniej zdefiniowane są niezbędne style bazowe.
- następnie dodawane są style z poprzedniego zakresu lub nowe style.
Poniższy diagram przedstawia strukturę zapytań media i stylów dla strony z dwoma punktami przełamania: 768px i 1024px.
W pierwszej kolejności tworzona jest wersja stylu podstawowego i mobilnego. Wszystkie style dla szerszych ekranów są zamykane w odpowiednich zapytaniach o media. Znaczniki HTML nie ulegają zmianie.
Przy podejściu Mobile First w zapytaniach media, w większości wypadków wykorzystuje się funkcję media min-width, ponieważ style są zapisywane od mniejszego do większego rozmiaru viewportu.
selector {
/* Style bazowe */
}
@media (min-width: szerokość-tabletu) {
selector {
/* Style tabletu */
}
}
@media (min-width: szerokość-pulpitu) {
selector {
/* Style pulpitu */
}
}
Zalety takiego designu:
- Uporządkowanie kodu, bo pomaga nam bieg dokumentu i model blokowy przy pozycjonowaniu elementów interfejsu.
- „Dziedziczenie stylów" (inherit) od wąskich na szerokie ekrany.
- Minimalne zastępowanie stylów pozycjonowania.
4.3 Range styles (style zakresu)
W większości sytuacji wystarczy skorzystać z tej funkcji min-width i dodać lub zastąpić style. Są jednak chwile, gdy korzystanie z funkcji media max-width sprawia, że kod jest prostszy i bardziej przejrzysty.
Rozważmy sytuację:
- Na urządzeniu mobilnym (do 767px) do elementu należy dodać ramkę.
- Dla tabletu (w zakresie od 768px do 1023px) element powinien posiadać cień.
- Dla urządzeń desktopowych (od 1024px) element nie ma cienia.
Wykorzystanie wyłącznie min-width doprowadzi do tego, że w punkcie przełamania 768px będziemy musieli wyzerować style ramki. A w punkcie przełamania 1024px będziemy zerować style cienia. To kiepskie rozwiązanie.
/* ❌ ŹLE */
.box {
border: 1px solid black;
}
@media (min-width: 768px) {
.box {
border: none;
box-shadow: 2px 2px 4px 2px black;
}
}
@media (min-width: 1024px) {
.box {
box-shadow: none;
}
}
W takich sytuacjach lepszym rozwiązaniem może być zamknięcie określonych stylów w określonych zakresach viewportu.
Aby rozwiązać ten problem, używamy funkcji media max-width.
/* ✅ DOBRZE */
@media (max-width: 767px) {
.box {
border: 1px solid black;
}
}
@media (min-width: 768px) and (max-width: 1023px) {
.box {
box-shadow: 2px 2px 4px 2px black;
}
}
4.4 Adaptive grid (siatka adaptacyjna)
Rozważmy technikę tworzenia adaptacyjnej siatki elementów, gdy liczba wierszy i elementów w rzędzie zmienia się w zależności od szerokości viewportu.
Użyjmy następującego znacznika HTML i umieśćmy go div.element w środku div.container zgodnie z ilustracją (makietą) z dwoma punktami przełamania 768px i 1024px.
<div class="container">
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
<div class="element">4</div>
<div class="element">5</div>
<div class="element">6</div>
</div>
Zapiszmy podstawowe style i style na urządzenia mobilne, czyli bez zapytania media.
Nie ma stylów elementów związanych konkretnie z pozycjonowaniem. Istnieją jedynie style kontenera, służące do regulacji jego szerokości, centrowania i ustawiania odstępu pomiędzy elementami.
.container {
display: flex;
flex-direction: column;
gap: 5px;
max-width: 1170px;
min-width: 320px;
maring: 0 auto;
}
Minimalną i maksymalną szerokość kontenera określa szablon - jest to szerokość treści strony w wersji mobilnej i desktopowej.
W pierwszym punkcie przełamania 768px konieczne jest ułożenie elementów poziomo, aby mieściły się one w dwóch rzędach. Aby to zrobić, zmień kierunek osi głównej i spraw, aby kontener był wieloliniowy. Dla elementów ustalamy wielkość według znanego już wzoru z techniki tworzenia siatek.
@media (min-width: 768px) {
.container {
flex-direction: row;
flex-wrap: wrap;
gap: 10px;
}
.element {
flex-basis: calc((100% - 10px) / 2);
}
}
Zwróć uwagę na gap, która się zmieniła. Zrobiono to specjalnie, aby pokazać, że przestrzenie między elementami mogą zmieniać się w różnych punktach przełamania. Wszystko zależy od designu, dlatego należy być uważnym i sprawdzć, czy wartości właściwości zmieniają się na różnych urządzeniach.
Ostatnim krokiem będzie zmiana odstępu, ilości i rozmiaru elementów punktu przełamania 1024px zgodnie z makietą.
@media screen and (min-width: 1024px) {
.container {
gap: 15px;
}
.element {
flex-basis: calc((100% - 30px) / 3);
}
}
5.1 Adaptacyjna grafika
Fizyczne piksele (device pixel albo hardware pixel) to najmniejsze elementy każdego ekranu (jego matrycy), z których każdy ma swój własny kolor i jasność.
Rozdzielczość ekranu to liczba fizycznych pikseli na ekranie urządzenia. Na przykład rozdzielczość 1920x1080 oznacza, że ekran ma fizyczną szerokość 1920 pikseli i wysokość 1080. Jeśli to pomnożysz, całkowita liczba pikseli na takim ekranie wyniesie 2073600.
Zagęszczenie pikseli (pixel density) to liczba fizycznych pikseli zawartych w jednym calu. Mierzona jest w jednostkach ppi (pixels per inch). Im wyższa gęstość, tym mniejszy rozmiar pikseli i tym więcej ich na ekranie.
Na urządzeniach z ekranami o większej gęstości pikseli więcej fizycznych pikseli mieści się na tym samym rozmiarze ekranu ze względu na mniejszy rozmiar piksela. Zwiększa to jakość i klarowność obrazu, sprawia, że obrazy są bardziej nasycone i realistyczne.
5.2 Piksele CSS (device-independent pixels)
Na zwykłych ekranach jeden piksel CSS odpowiada jednemu pikselowi urządzenia fizycznego.
W przypadku powiększania i na ekranach o dużej gęstości pikseli w jednym pikselu CSS może znajdować się więcej niż jeden piksel fizyczny. Powiedzmy, że mamy blok pikseli 2x2.
Wiemy, że wymiary w pliku CSS i w dokumencie HTML są określane w pikselach CSS.
- Na zwykłych ekranach element będzie zajmować obszar 2x2 pikseli fizycznych.
- Na ekranach, na przykład z zagęszczeniem 2, ten sam blok otrzyma 4x4 fizycznych pikseli. Czyli: dwa razy więcej w pionie i poziomie.
Zatem na ekranach o dwukrotnie większym standardowym zagęszczeniu pikseli liczba pikseli jest 4 razy większa niż na normalnych ekranach.
5.3 Piksele mapy bitowej (bitmap pixels)
Piksele mapy bitowej (bitmap pixels), rzadziej: piksele rastrowe — najmniejsze części tworzące obraz rastrowy (png, jpg, gif itp.). Każdy piksel zawiera informację o swoim kolorze i położeniu w układzie współrzędnych obrazu.
W kodzie HTML lub CSS wymiary obrazu są określone w pikselach CSS.
- Podczas wyświetlania na normalnym ekranie jeden piksel mapy bitowej odpowiada jednemu pikselowi CSS.
- Na ekranach o zagęszczeniu 2 każdy piksel mapy bitowej jest mnożony czterokrotnie, co prowadzi do utraty jakości obrazu, który nie jest przygotowany do retiny (dostosowania).
Dlatego obrazy rastrowe dla ekranów o zwiększonej gęstości pikseli muszą mieć większą liczbę pikseli rastrowych. Zagwarantuje to ich normalną jakość podczas wyświetlania w przeglądarce.
5.4 Retinyzacja grafiki
Ekrany o zwiększonej gęstości pikseli wymagają specjalnie przygotowanych zasobów. Tekst i grafika wektorowa wyglądają równie dobrze na każdym ekranie.
Retinyzacja — to technika przygotowania grafiki rastrowej. Aby to zrobić, musisz wyeksportować większy obraz z szablonu. Aby pokazać obraz 200x300 pikseli CSS na ekranie z zagęszczeniem 2, konieczne jest przygotowanie jego wariantu w rozmiarze 400x600, a dla ekranu z zagęszczeniem 3 ten obraz powinien wynosić 600x900.
Poniższy przykład wykorzystuje usługę obrazów online.
Przesyłane są trzy zdjęcia:
- 320x240 — dla zwyczajnych ekranów (1x),
- 640x480 — dla ekranów z zagęszczeniem 2 (2x)
- 960x720 — dla ekranów z zagęszczeniem 3 (3x)
Rozmiar wszystkich elementów img jest taki sam — 320x240 pikseli CSS.
<!-- Image format from an image service.: https://picsum.photos/id/237/width/height -->
<!-- x1 -->
<img
src="https://picsum.photos/id/237/320/240"
alt="Cute puppy"
width="320"
height="240"
/>
<!-- x2 -->
<img
src="https://picsum.photos/id/237/640/480"
alt="Cute puppy"
width="320"
height="240"
/>
<!-- x3 -->
<img
src="https://picsum.photos/id/237/960/720"
alt="Cute puppy"
width="320"
height="240"
/>
Rozmiar wszystkich elementów img jest taki sam — 320x240 pikseli CSS.
Jeśli przejdziesz do przykładu za pomocą telefonu lub po prostu powiększysz stronę z przykładem, zobaczysz, że:
- Pierwsze zdjęcie jest bardzo rozmyte.
- Drugie pozostaje dość wysokiej jakości.
- Trzecie jest zawsze wyraźne.
W przypadku grafiki rastrowej wystarczy jedynie przygotować wersje 1x i 2x . Większość ludzi o dobrym wzroku nie zauważy różnicy pomiędzy obrazami 2x i 3x, ale "waga" tego ostatniego będzie znacznie większa, co negatywnie wpłynie na prędkość jego ładowania.
Proces retynizacji
Proces przygotowania składa się z:
- Eksport obrazów N razy większych niż rozmiar oryginalny.
- Zapisanie dużych obrazów z odpowiednimi przedrostkami @2x i @3x. Dla wersji oryginalnej przedrostek nie jest konieczny.
Nie ma również potrzeby eksportowania i przesyłania największego obrazu.
5.5 Obrazy elastyczne i responsywne
Obrazy elastyczne
Wyobraź sobie obraz o rozmiarze 1200x600 pikseli. Świetnie wygląda na szerokim ekranie. A co się stanie, jeśli otworzymy stronę na telefonie lub tablecie? Kiepska sprawa.
Obraz nadal będzie mieć szerokość 1200 pikseli. W związku z tym pojawi się poziomy pasek przewijania. A obraz będzie niewyraźny na ekranach o zwiększonym zagęszczeniu pikseli.
Obrazy responsywne
Obrazy reposnsywne — to termin używany do opisania zestawu technik stosowanych w HTML i CSS, dzięki którym zawartość i obrazy tła wyglądają równie dobrze na urządzeniach o różnych rozmiarach i gęstościach ekranów. Najłatwiejszym sposobem wdrożenia responsywności jest elastyczność grafiki, czyli użycie jednego obrazu dla wszystkich urządzeń i globalne określenie zestawu właściwości CSS (patrz kod poniżej).
img {
display: block;
max-width: 100%;
}
- Obraz musi być blokowy, aby usunąć dolną „przerwę" elementu wiersza.
- Maksymalna szerokość 100% gwarantuje, że w razie potrzeby obraz zostanie zmniejszony. Jednocześnie nie będzie się rozciągać bardziej, niż 100% swojej pierwotnej szerokości, aby nie tracić jakości.
Tak działa prosta technika elastycznego obrazu - jeden obraz dla wszystkich urządzeń, który dopasowuje się do aktualnej szerokości elementu nadrzędnego.
.obrazy-responsywne-main-container_5-5 {
display: flex;
flex-wrap: wrap;
justify-content: center;
.obrazy-responsywne-container_5-5 {
max-width: 960px;
min-width: 320px;
margin: 0 auto;
img {
display: block;
max-width: 100%;
}
}
}
5.6 Obrazy responsywne
Aby umożliwić przeglądarce ładowanie różnych obrazów:
- developer określa listę obrazów dostępnych do pobrania, wraz z ich rozmiarami i gęstością pikseli, za pomocą atrybutów srcset i sizes.
- przeglądarka wybiera obraz, odpowiadający zagęszczeniu pikseli ekranu i szerokości viewportu, i pobiera go.
Załóżmy, że developer określił dwa dostępne obrazy: 300x300 i 600x600 pikseli. Jeśli przeglądarce wystarczy obraz 300x300, oznacza to czterokrotną oszczędność wagi ładowanego obrazu. Im mniejszy rozmiar ekranu urządzenia, tym szybsze pobieranie.
<img srcset="./img/photo.jpg 1x, ./img/photo@2x.jpg 2x" />
Aby przeglądarka wybrała odpowiedni obraz, konieczne jest użycie elementu img z atrybutem srcset.
Atrybut srcset określa listę wersji obrazu w różnych rozmiarach. Po ścieżce obrazu dodawany jest deskryptor x, który informuje przeglądarkę, dla jakiej gęstości ekranu jest odpowiednia ta wersja obrazu. Lista tych zgłoszeń jest oddzielona przecinkiem.
<img
srcset="./img/photo.jpg 1x, ./img/photo@2x.jpg 2x"
src="./img/photo.jpg"
alt="Opis obrazów dla wszystkich wersji"
/>
W atrybucie src obowiązkowo należy podać wersję obrazu w jakości standardowej. Ta wersja obrazu zostanie użyta, jeśli przeglądarka jest starsza i nie wie, jak obsługiwać atrybut srcset.
5.7 Obrazy tła
Rastrowe obrazy tła należy również przygotować dla ekranów o dużym zagęszczeniu. Aby dokonać retinizacji obrazu tła, należy ustawić rozmiar tła elementu równy rozmiarowi samego elementu.
.box {
width: 200px;
height: 300px;
background-image: url('photo.png');
background-size: 200px 300px;
}
Jeśli element nie ma stałej szerokości i wysokości, czyli zależy od szerokości elementu nadrzędnego, rozmiar tła można ustawić na wartość cover. W tym wypadku obraz w pełni wypełni tło.
.box {
background-image: url('photo.png');
background-size: cover;
}
Na jakość wyświetlania tła wpływa również zagęszczenia pikseli ekranu. Aby określić zagęszczenie pikseli ekranu CSS, dostępne są funkcje media: resolution, min-resolution i max-resolution. Pozwalają sprawdzić dokładne dopasowanie oraz minimalną/maksymalną wartość zagęszczenia pikseli urządzenia.
Wewnątrz żądania media ze sprawdzeniem zagęszczenia pikseli nadpisujemy ścieżkę do obrazu tła.
/* Style bazowe i 1x grafika */
.box {
width: 200px;
height: 300px;
background-image: url('photo.png');
background-size: 200px 300px;
}
/* Określamy nową ścieżkę do obrazu jeśli zagęszczenie obrazu wynosi minimum 2x */
@media (min-resolution: 192dpi) {
.box {
background-image: url('photo@2x.png');
}
}
Wartością funkcji media sprawdzenia zagęszczenia pikseli to jednostka dpi (dots per inch), czyli ilość fizycznych pikseli na cal ekranu.
Na ekranach o standardowym zagęszczeniu pikseli wynoszącym jeden cal jest 96 punktów. Dlatego w celu sprawdzenia ekranów z zagęszczeniem 2 i więcej podajemy wartość 192dpi (96x2).