Składnia opisowa

W tym module dowiesz się, jak udostępnić przeglądarce różne obrazy, tak aby mogła ona wybierać, co należy wyświetlać. srcset nie jest metodą zamiany źródeł obrazów w określonych punktach przerwania ani nie ma na celu zamiany jednego obrazu na drugi. Dzięki tym składni rozwiązać bardzo trudny problem, niezależnie od nas: bezproblemowego żądania i renderowania źródła obrazu dostosowanego do kontekstu przeglądania użytkownika, takich jak rozmiar widocznego obszaru, gęstość wyświetlacza, preferencje użytkownika, przepustowość i wiele innych czynników.

To bardzo satysfakcjonująca kwestia – z pewnością więcej, niż przypuszczamy, że po prostu zaznaczamy obraz na potrzeby internetu, niż mamy dostęp do informacji.

Element <img> o stałej szerokości będzie zajmować taką samą ilość widocznego obszaru w dowolnym kontekście przeglądania, niezależnie od gęstości wyświetlacz – liczba fizycznych pikseli, które składają się na ekran. Na przykład obraz o stałej szerokości wynoszącej 400px będzie zajmować prawie cały widoczny obszar przeglądarki na oryginalnym Google Pixelu i w znacznie nowszych Pixelu 6 Pro – oba urządzenia mają znormalizowany współczynnik 412px. Szeroki widoczny piksel logiczny.

Pixel 6 Pro ma jednak o wiele wyższy wyświetlacz: Pixel 6 Pro ma jednak fizyczną rozdzielczość 1440 × 3120 pikseli, Pixel ma 1080 × 1920 pikseli, czyli liczbę pikseli sprzętowych, z których składa się ekran.

Stosunek między pikselami logicznymi urządzenia a pikselami fizycznymi to współczynnik pikseli urządzenia używany na danym wyświetlaczu (DPR). DPR to oblicza się, dzieląc rzeczywistą rozdzielczość ekranu urządzenia przez liczbę pikseli CSS widocznego obszaru.

DPR 2 w oknie konsoli.

Wartość DPR oryginalnego telefonu Pixel to 2,6, a Pixel 6 Pro – 3,5.

iPhone 4, pierwsze urządzenie z parametrem DPR wyższym niż 1, zgłasza współczynnik pikseli równy 2. Fizyczna rozdzielczość ekranu to podwoić rozdzielczość logiczną. W przypadku wszystkich urządzeń sprzed iPhone'a 4 wartość DPR wynosiła 1: jeden piksel logiczny na 1 piksel fizyczny.

Jeśli wyświetlisz na wyświetlaczu obraz o szerokości 400px, z wartością DPR wynoszącą 2, każdy piksel logiczny jest renderowany przez cztery fizyczne piksele wyświetlacza: dwa poziomy i dwa pionowe. Obraz nie korzystnie wpływa na wyświetlacz o dużej gęstości – będzie wyglądał tak samo jak w przypadku wyświetlacza z DPR wynoszącym 1. Oczywiście wszystkie „narysowane” przez mechanizm renderowania przeglądarki – tekst, kształty CSS czy pliki SVG na przykład tak, aby pasowały do większych ekranów. Ale jak wiesz z artykułu Formaty i kompresja obrazów, obrazy rastrowe są stałe siatki pikseli. Chociaż nie zawsze jest to oczywiste, obraz rastrowy powiększony do wyświetlacza o większej gęstości będzie wyglądać tak mają niską rozdzielczość w porównaniu z otaczającą ją stroną.

Aby można było zapobiec skalowaniu w górę, renderowany obraz musi mieć wewnętrzną szerokość co najmniej 800 pikseli. Przy skalowaniu w dół by zmieścić przestrzeń w układzie o szerokości 400 pikseli logicznych, gęstość pikseli 800 pikseli jest 2 razy większa – na wyświetlaczu o wartości DPR wynoszącej 2. będzie ładnie i ostrożnie.

Zbliżenie na płatek kwiatu o różnej gęstości.

Wyświetlacz o DPR równy 1 nie może wykorzystać zwiększonej gęstości obrazu, więc zostanie zmniejszony, by dopasować i jak wiesz, obraz zmniejszony będzie wyglądał dobrze. Na wyświetlaczu o niskiej gęstości obrazu można wyświetlić obraz o większej gęstości niż inne obrazy o niskiej rozdzielczości.

Jak już wiesz z sekcji Obraz i wydajność, użytkownik z wyświetlaczem o niskiej gęstości wyświetla źródło obrazu zmniejszone do 400px. będzie potrzebować tylko źródła o niezmiennej szerokości 400px. Choć dużo większy obraz spodoba się wszystkim użytkownikom, duży, źródło obrazów w wysokiej rozdzielczości renderowane na małym wyświetlaczu o niskiej gęstości wygląda jak inne małe obrazy o niskiej gęstości, ale działa znacznie wolniej.

Jak można się domyślić, urządzenia mobilne o wartości DPR wynoszącej 1 są rzadko chociaż jest to nadal typowe rozwiązanie w kategorii „komputery” konteksty przeglądania. Według danych według danych Matta Hobbsa wśród około 18% sesji przeglądania w GOV.UK z listopada 2022 r. wskazano 1 DPR. Choć obrazy w wysokiej rozdzielczości wyglądają zgodnie z oczekiwaniami użytkowników, wiąże się to ze znacznie większą przepustowość i wyższym kosztem przetwarzania. Dotyczy to zwłaszcza użytkowników starszych i mniej zaawansowanych urządzeń, które nadal mają wyświetlacze o niskiej gęstości.

Korzystając z funkcji srcset, masz pewność, że tylko urządzenia z wyświetlaczami o wysokiej rozdzielczości otrzymują źródła obrazów wystarczająco duże, by wyglądały dobrze, bez tego samego niż w przypadku użytkowników z wyświetlaczami o niższej rozdzielczości.

Atrybut srcset identyfikuje co najmniej jeden rozdzielany przecinkami kandydat do wyrenderowania obrazu. Każdy kandydat składa się z: 2 rzeczy: adres URL (jak w src) oraz składnia, która opisuje źródło obrazu. Każdy kandydat w stanie srcset jest określana przez jej nieodłączną szerokość („w”) lub zamierzoną gęstość („składnia x”).

Składnia x to skrót oznaczający „to źródło jest odpowiednie dla wyświetlacza o tej gęstości”. Ciąg znaków 2x oznacza jako odpowiedni dla wyświetlaczy z DPR równym 2.

<img src="low-density.jpg" srcset="double-density.jpg 2x" alt="...">

W przeglądarkach, które obsługują interfejs srcset, zostaną wyświetlone 2 możliwości: double-density.jpg. 2x określa jako odpowiednią w przypadku wyświetlaczy z DPR równym 2 i low-density.jpg w atrybucie src – kandydat został wybrany, jeśli nic nie jest bardziej odpowiednie znaleziono w: srcset. W przypadku przeglądarek, które nie obsługują srcset, atrybut i jego zawartość będą ignorowane – zawartość atrybutu src jak zwykle będziemy wysyłać prośby.

Wartości podane w atrybucie srcset łatwo pomylić się z instrukcjami. Dzięki temu 2x informuje przeglądarkę, że powiązany plik źródłowy mógłby być używany na wyświetlaczu z DPR równym 2, czyli z informacjami o samym źródle. Nic nie wie przeglądarka informuje przeglądarkę, jak z niego skorzystać, po prostu informuje przeglądarkę, w jaki sposób może je wykorzystać. To subtelna, ale ważna różnica: to obraz o podwójnej gęstości, a nie obraz używany na wyświetlaczu o podwójnej gęstości.

Różnica między składnią, która brzmi „to źródło jest odpowiednie dla wyświetlaczy 2x”. i drugi z napisem „Używaj tego źródła na ekranach 2x” jest lekki, ale gęstość wyświetlania to tylko jeden z wielu połączonych czynników, które przeglądarka uwzględnia przy podejmowaniu decyzji o kandydacie. tylko niektóre z nich są znane. Na przykład: pojedynczo możesz stwierdzić, że użytkownik włączył oszczędzanie przepustowości w ustawieniach przeglądarki za pomocą zapytania multimedialnego w prefers-reduced-data i korzystanie z tego ustawienia, aby zawsze wyświetlać użytkownikom obrazy o niskiej gęstości. bez względu na gęstość ich wyświetlania. Jeśli jednak nie zostaną wdrożone konsekwentnie przez wszystkich programistów i na każdej stronie, nie będą one zbyt przydatne dla użytkownika. W jednej lokalizacji ich preferencje mogą być respektowane, a w drugiej – ściana obrazów z obniżoną przepustowością.

Celowo niejasny algorytm wyboru zasobów używany przez srcset/sizes pozwala przeglądarkom wybrać mniejszą gęstość obrazów ze spadkiem przepustowości lub ze względu na preferencję zminimalizowania użycia danych, przy czym nie ponosimy odpowiedzialności za to, jak, kiedy i co Jaki jest próg? Nie ma sensu angażować się w odpowiedzialność i zapewniać dodatkową pracę, ponieważ przeglądarka jest lepiej dostosowana do Twoich potrzeb.

Opisowanie szerokości za pomocą funkcji w

Funkcja srcset akceptuje drugi typ deskryptora dla kandydatów jako źródła obrazu. To znacznie potężniejsze narzędzie, a do naszych celów znacznie łatwiejszy do zrozumienia. Zamiast zgłaszać propozycję jako mającą wymiary odpowiednie dla danej gęstości wyświetlania, składnia w opisuje nieodłączną szerokość każdego źródła kandydatów. I tak, każdy kandydat jest identyczny dla swoich rozmiarów – z takim samym przycięciem i formatem obrazu. W tym przypadku jednak przeglądarka użytkownika ma wybierać spośród 2 kandydatów: small.jpg, czyli źródło o stałej szerokości 600 pikseli, oraz „large.jpg” (źródło o stałej szerokości 1200 pikseli).

srcset="small.jpg 600w, large.jpg 1200w"

Nie informuje to przeglądarki, co ma zrobić z tymi informacjami, a jedynie dostarcza listę kandydatów, które mogą wyświetlić obraz. Zanim przeglądarka zdecyduje, które źródło wyświetlić, musisz podać mu trochę więcej informacji: z opisem sposobu renderowania obrazu na stronie. Aby to zrobić, użyj atrybutu sizes.

Opisywanie wykorzystania za pomocą funkcji sizes

Przeglądarki są niezwykle wydajne pod względem przenoszenia obrazów. Żądania komponentów z obrazem będą inicjowane długo przed żądaniami arkuszy stylów lub kodu JavaScript – często jeszcze przed pełną analizą znaczników. Gdy przeglądarka wysyła te żądania, nie zawiera żadnych informacji o stronie (oprócz znaczników) – być może nawet nie zainicjował żądań w przypadku zewnętrznych arkuszy stylów, nie wspominając o ich zastosowaniu. W momencie, gdy przeglądarka analizuje znaczniki i zaczyna tworzyć z zewnątrz zawiera tylko informacje z poziomu przeglądarki: wielkość obszaru widocznego dla użytkownika, gęstość pikseli na wyświetlaczu, preferencji użytkownika itd.

Nie mówi nam to o tym, jak obraz ma być renderowany w układzie strony – nie może nawet korzystać z widocznego obszaru. jako proxy dla górnej granicy rozmiaru img, ponieważ może zajmować kontener przewijany w poziomie. Musimy więc udostępnić przeglądarce te informacje i użyć znaczników. To wszystko, co będziemy mogli zastosować w odpowiedzi na te żądania.

Podobnie jak srcset, właściwość sizes służy do udostępniania informacji o obrazie od razu po przeanalizowaniu znacznika. Tak samo jak srcset to skrótowe określenie „tutaj są pliki źródłowe i ich właściwe rozmiary”, Atrybut sizes to skrót od „tutaj” to rozmiar renderowanego obrazu w układzie. Sposób opisywania obrazu odnosi się do widocznego obszaru – i to ponownie – rozmiar to jedyne informacje o układzie, które przeglądarka otrzymuje po wysłaniu żądania grafiki.

Może się to wydawać nieco skomplikowane w druku, ale w praktyce jest to znacznie łatwiejsze:

<img
 
sizes="80vw"
 
srcset="small.jpg 600w, medium.jpg 1200w, large.jpg 2000w"
 
src="fallback.jpg"
 
alt="...">

Tutaj wartość sizes informuje przeglądarkę, że przestrzeń w układzie, w której znajduje się element img, ma szerokość 80vw–80% w widocznym obszarze. Pamiętaj, że to nie jest instrukcja, a rozmiar obrazu podany w układzie strony. Nie widzisz tego tekstu zajmuje 80% widocznego obszaru," ale „po wyrenderowaniu strony ten obraz będzie zajmował 80% widocznego obszaru”.

Jako programista nie musisz już nic robić. Podana przez Ciebie lista źródeł kandydatów w języku: srcset oraz szerokość obrazu została przez Ciebie dokładnie opisana w sizes. Podobnie jak w przypadku składni x w srcset, reszta należy do przeglądarki.

Aby w pełni zrozumieć, jak wykorzystujemy te informacje, poświęćmy chwilę na omówienie decyzji, które przeglądarka użytkownika wykonuje po napotkaniu tych znaczników:

Informujesz przeglądarkę, że ten obraz zajmuje 80% dostępnego widocznego obszaru, więc jeśli mamy wyrenderować ten img urządzenia z widocznym obszarem o szerokości 1000 pikseli, ten obraz zajmie 800 pikseli. Następnie przeglądarka podzieli tę wartość na to szerokości każdego z kandydatów do źródła obrazu określonych w srcset. Najmniejsze źródło ma naturalny rozmiar 600 pikseli, czyli 600÷800 = 0,75. Nasz średni obraz ma 1200 pikseli szerokości: 1200 ÷ 800=1,5. Największy obraz ma 2000 pikseli szerokości: 2000 ÷ 800=2,5.

Wyniki tych obliczeń (.75, 1.5 i 2.5) są w praktyce dostosowane do potrzeb użytkownika rozmiar widocznego obszaru. Przeglądarka ma też dostęp do informacji o gęstości interfejsu użytkownika, dlatego podejmuje szereg decyzji:

Przy tym rozmiarze widocznego obszaru propozycja small.jpg jest odrzucana niezależnie od gęstości interfejsu użytkownika – obliczona wartość DPR jest niższa. niż 1, to źródło wymagałoby skalowania w górę u każdego użytkownika, więc jest nieodpowiednie. Na urządzeniu z DPR 1 medium.jpg udostępnia: najbliższe dopasowanie – to źródło nadaje się do wyświetlania przy DPR o wartości 1.5, więc jest ono nieco większe, niż jest to konieczne. Pamiętaj jednak, że płynny proces. Na urządzeniu z DPR ustawionym na 2 najbardziej trafne jest ustawienie large.jpg, więc jest ono wybierane.

Jeśli ten sam obraz zostanie wyrenderowany na obszarze o szerokości 600 pikseli, wynik będzie zupełnie inny: 80vw to teraz 480 pikseli. Gdy dzielimy źródła w porównaniu z tymi szerokościami uzyskujemy 1.25, 2.5 i 4.1666666667. Przy tym rozmiarze widocznego obszaru zostanie wybrany element: small.jpg na 1 urządzeniach, a medium.jpg będzie na 2 urządzeniach.

Ten obraz będzie wyglądać tak samo we wszystkich tych kontekstach przeglądania: wszystkie nasze pliki źródłowe są dokładnie takie same, różnią się od wymiarów. i każdy z nich jest renderowany z taką intensywnością, na ile pozwala na to gęstość wyświetlania. Zamiast udostępniać large.jpg wszystkim użytkownikom, w celu uwzględnienia największych widocznych obszarów i wyświetlaczy o największej gęstości, użytkownicy zawsze zobaczą najmniejszą odpowiednią propozycję. Dzięki składni opisowej, a nie nakazowej, nie musisz ręcznie ustawiać punktów przerwania i brać pod uwagę przyszłe widoczne obszary Dyrektywa DPR – wystarczy podać przeglądarce informacje i pozwolić, aby zrobiła to za Ciebie.

Wartość sizes odnosi się do widocznego obszaru i jest całkowicie niezależna od układu strony, więc stanowi dodatkową warstwę widżetów. Nieczęsto zdarza się, że obraz zajmuje tylko procent widocznego obszaru bez marginesów, dopełnienia czy wpływu. od innych elementów na stronie. Często trzeba wyrażać szerokość obrazu za pomocą kombinacji jednostek, procenty, em, px itd.

Na szczęście możesz tutaj użyć interfejsu calc(). Każda przeglądarka z natywną obsługą obrazów elastycznych będzie też obsługiwać język calc(), co umożliwi nam zestaw jednostek CSS – np. obraz zajmujący pełną szerokość widocznego obszaru użytkownika, z pomniejszeniem 1em marginesu po każdej stronie:

<img
   
sizes="calc(100vw-2em)"
   
srcset="small.jpg 400w, medium.jpg 800w, large.jpg 1600w, x-large.jpg 2400w"
   
src="fallback.jpg"
   
alt="...">

Opisywanie punktów przerwania

Jeśli poświęcasz dużo czasu na pracę z układami elastycznymi, prawdopodobnie zauważysz, że w tych przykładach brakuje czegoś: miejsce zajmowane przez obraz w układzie może się zmieniać między punktami przerwania układu. W takim przypadku musisz podać aby przekazać trochę więcej informacji do przeglądarki: funkcja sizes akceptuje rozdzielany przecinkami zestaw propozycji dla renderowanego rozmiaru obraz, tak samo jak srcset akceptuje rozdzielane przecinkami propozycje źródeł obrazu. Warunki te używają znajomej składni zapytań o multimedia. Ta składnia jest dopasowywana w pierwszej kolejności: gdy tylko spełni warunek multimediów, przeglądarka przestaje analizować atrybut sizes i wartość została zastosowana.

Załóżmy, że masz obraz, który zajmuje 80% widocznego obszaru, minus jeden em dopełnienia po każdej stronie i w widocznych obszarach powyżej 1200 pikseli – włączone zajmuje całą szerokość widocznego obszaru.

  <img
     
sizes="(min-width: 1200px) calc(80vw - 2em), 100vw"
     
srcset="small.jpg 600w, medium.jpg 1200w, large.jpg 2000w"
     
src="fallback.jpg"
     
alt="...">

Jeśli widoczny obszar użytkownika ma więcej niż 1200 pikseli, calc(80vw - 2em) określa szerokość obrazu w naszym układzie. Jeśli Warunek (min-width: 1200px) nie jest zgodny, przeglądarka przechodzi do następnej wartości. Nie istnieje konkretna warunek mediów powiązany z tą wartością. Domyślnym ustawieniem jest 100vw. Jeśli ten atrybut sizes ma zostać zapisany za pomocą Zapytania o multimedia (max-width):

  <img
     
sizes="(max-width: 1200px) 100vw, calc(80vw - 2em)"
     
srcset="small.jpg 600w, medium.jpg 1200w, large.jpg 2000w"
     
src="fallback.jpg"
     
alt="...">

Jasno: „czy (max-width: 1200px) pasuje? Jeśli nie, przejdź dalej. Kolejna wartość (calc(80vw - 2em)) nie ma warunku kwalifikacji, więc to jest wybrane.

Gdy już udostępnisz przeglądarce wszystkie informacje o elemencie img – potencjalne źródła, właściwe szerokości i sposobu pokazania obrazu użytkownikowi – przeglądarka na podstawie niejednoznacznego zestawu reguł określa, co zrobić z obrazem te informacje. Jeśli brzmi to niejasno, to dlatego, że tak jest – z założenia. Algorytm wyboru źródła zakodowany w Specyfikacja HTML jest wyraźnie niejednoznaczna w kwestii wyboru źródła. Gdy źródła, ich deskryptory i sposób Wyrenderowany obraz został w całości przeanalizowany, przeglądarka może zrobić, co tylko zechce – nie można stwierdzić, co wybrane przez przeglądarkę.

Składnia, która brzmi „Używaj tego źródła na wyświetlaczu o wysokiej rozdzielczości”. bywa to przewidywalne, ale nie rozwiązuje problemu dzięki obrazom w układzie elastycznym, co pozwala oszczędzić przepustowość dla użytkownika. Gęstość pikseli na ekranie jest w związku z internetem tylko w sposób luźny. jeśli w ogóle używa się szybkości połączenia. Jeśli używasz laptopa wysokiej jakości, ale przeglądasz internet w ramach połączenia z pomiarem, w połączeniu z internetem lub gdy korzystasz z niepewnego połączenia Wi-Fi w samolocie, warto zrezygnować ze źródeł zdjęć o wysokiej rozdzielczości niezależnie jakość wyświetlacza.

Pozostawienie ostatecznej decyzji przeglądarki pozwala znacznie poprawić wydajność, niż byłoby to możliwe w przypadku ściśle składni. Na przykład: w większości przeglądarek użycie składni img z użyciem składni srcset lub sizes nigdy nie będzie przeszkadzać w żądaniu źródła o mniejszej wersji. wymiar użytkownika niż ten, który znajduje się już w pamięci podręcznej przeglądarki. Jaki sens ma przesłanie nowej prośby dotyczącej źródła? wyglądałoby identycznie, gdyby przeglądarka mogła płynnie skalować obraz w przypadku źródła obrazów, które już ma? Jeśli jednak użytkownik dostosuje ustawienia aż do momentu, gdy potrzebny jest nowy obraz, by uniknąć skalowania w górę, to żądanie nadal jest wysyłane, więc wszystko tak, jak chcesz.

Brak całkowitej kontroli może brzmieć strasznie, ale ponieważ używasz plików źródłowych o identycznych nie będziemy raczej przedstawiać użytkownikom „zepsutych” niż w przypadku pojedynczego źródła src, niezależnie od decyzji podejmowanych przez przeglądarkę.

Używasz sizes i srcset

To bardzo dużo informacji – zarówno dla Ciebie, jak i dla użytkownika, a także dla przeglądarki. Zarówno srcset, jak i sizes to gęsta składnia, opisujący szokującą ilość informacji za pomocą stosunkowo małej liczby znaków. To znaczy, że z założenia tworzenie Taki składnia jest mniej zwięzła i łatwiejsza do analizy przez ludzi. Może to utrudnić ich analizowanie przez przeglądarkę. tym większe prawdopodobieństwo wystąpienia błędów parsera lub niezamierzonych różnic w zachowaniu. z jednej przeglądarki do drugiej. Ma to jednak zaletę: składnia łatwiejsza do odczytania przez maszyny to łatwiejsza składnia. przez firmę Google.

srcset to oczywiste rozwiązanie dla automatyzacji. Nieczęsto zdarza się, że ręcznie tworzysz wiele wersji zdjęć na zamiast automatyzacji procesu, korzystając z programu uruchamiającego zadania, takiego jak Gulp, czyli program do tworzenia pakietów, taki jak Webpack, CDN, takie jak Cloudinary, lub funkcje wbudowane w wybrany przez Ciebie CMS. Mamy wystarczającą ilość informacji, aby wygenerować nasze źródła z góry system miałby wystarczającą ilość informacji, aby zapisać je w prawidłowym atrybucie srcset.

sizes jest nieco trudniejsze do zautomatyzowania. Jedynym sposobem, w jaki system może obliczyć rozmiar obrazu w jest wyrenderowany układ. Na szczęście pojawiło się wiele narzędzi dla programistów, procesu ręcznego pisania atrybutów sizes z jakością nieosiągalną ręcznie. Na przykład respImageLint to fragment kodu służący do sprawdzania atrybutów sizes. pod kątem dokładności i przedstawiać sugestie dotyczące poprawy. Naruszenia projektu Lazysizes i zwiększ wydajność dzięki opóźnieniu żądań obrazów do czasu określenia układu, co umożliwi JavaScript wygeneruje dla Ciebie sizes wartości. Jeśli używasz w pełni platformy renderowania po stronie klienta, np. React lub Vue, musisz użyć funkcji liczba rozwiązań do tworzenia lub generowania atrybutów srcset i sizes, które omówimy bardziej szczegółowo w CMS i platformach.