2015-02-23 10 views
9

Próbuję zrozumieć moją nową "srcset" atrybutu "img". Stworzyłem prostą stronę testową, ale zachowanie, które widzę w przeglądarkach, jest zaskakujące.Czy coś jest nie tak z moją definicją srcset lub czy aktualna obsługa przeglądarki jest słaba?

pierwsze, tutaj jest strona testowa:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="utf-8" /> 
    <meta name="viewport" content="width=device-width, initial-scale=1" /> 
    <title>Test Page</title> 
    <style type="text/css"> 
section.wrapper { 
    width: 100%; 
    text-align: center; 
} 

section.wrapper div { 
    margin: 0 auto; 
} 

section.wrapper div img { 
     width: 288px; 
     height: 216px; 
} 

@media (min-width: 30em) { } 

@media (min-width: 40em) { 
    section.wrapper div img { 
      width: 576px; 
      height: 432px; 
    } 
} 

@media (min-width: 48em) { } 

@media (min-width: 64em) { 
    section.wrapper div img { 
     width: 720px; 
     height: 540px; 
    } 
} 

@media (min-width: 72em) { 
    section.wrapper div img { 
     width: 960px; 
     height: 720px; 
    } 
} 

    </style> 
</head> 
<body> 

<section class="wrapper"> 
<div class="imagecontainer"> 
<img src="images/image-720.jpg" 
    srcset="images/image-1920.jpg 1920w, 
      images/image-1440.jpg 1440w, 
      images/image-1152.jpg 1152w, 
      images/image-960.jpg 960w, 
      images/image-840.jpg 840w, 
      images/image-720.jpg 720w, 
      images/image-576.jpg 576w, 
      images/image-420.jpg 420w, 
      images/image-288.jpg 288w, 
      images/image-144.jpg 144w" 
    sizes="(min-width: 40em) 576px, (min-width: 64em) 720px, (min-width: 72em) 960px, 100vw" 
    alt="Test" /> 
</div> 
</section> 

</body> 
</html> 

ja testuje na Retina MacBook Pro Retina oraz iPod, z Chrome/40.0.2214.115 i Firefox 35.0 (na MacBook Pro), a Chrome/40.0.2214.73 i Safari/600.1.4 (na iPodzie). Włączyłem obsługę srcset w przeglądarce Firefox. Testuję na szybkim połączeniu.

Próbuję zobaczyć, czy różne przeglądarki mogą inteligentnie uzyskać obraz o odpowiednim rozmiarze. Jednak nie zachowują się tak, jak bym się spodziewał.

W przypadku przeglądarek iOS oczekuję, że będą używać wartości zastępczej "100vw" z atrybutu "sizes". Ponieważ szerokość rzutni dla iPoda w trybie pionowym wynosi 320 pikseli, oczekiwałbym, że wybierze on obraz o rozdzielczości 288 pikseli lub 420 pikseli. Ewentualnie, biorąc pod uwagę, że jest to urządzenie Retina, zażądają obrazów o rozmiarach 576 pikseli lub 840 pikseli. Zamiast tego zarówno Safari, jak i Chrome żądają obrazu 1920 pikseli.

Pulpit przeglądarki Firefox generuje dwa żądania. Pierwszy dotyczy domyślnego obrazu określonego w atrybucie "src". Drugi to obraz 1920px. Zawsze żąda największego obrazu, niezależnie od aktualnego rozmiaru okna.

Pulpit Chrome jest najbardziej zbliżony do rzeczywistego pokazania tego, co uważam za prawidłowe zachowanie, chociaż nawet to jest dziwaczne. Jeśli mój plik testowy jest lokalny, zawsze pobiera obraz 1920 pikseli, niezależnie od rozmiaru widocznego obszaru. Jeśli umieściłem plik testowy na serwerze zdalnym, ma on ogólną preferencję dla obrazu 1152px (nawet gdy obraz powinien być renderowany przy 960px, co czyni 1920px logicznym wyborem dla urządzenia 2x). Jeśli wyczyści pamięć podręczną Chrome i zmieni rozmiar okna, a następnie przeładuję, będzie czasem wymagać mniejszych obrazów.

Jeśli widzę oczekiwane zachowanie dla tych przeglądarek, biorąc pod uwagę obecny stan obsługi każdej przeglądarki, to dla mnie jest jasne, że prawdopodobnie nie powinienem dostarczać obrazów o wyższej rozdzielczości - lepiej służyć obraz, który wygląda mniej perfekcyjnie na wyświetlaczu 2x, niż zrzucenie gigantycznego pliku JPEG na urządzenie mobilne przez możliwie wolne łącze. A jeśli Firefox zawsze będzie przyciągał domyślny obraz, powinienem raczej zrobić to mniejszym niż większym.

Czy jest jakiś problem z moim kodem, który powoduje te zachowania? A jeśli tak nie jest, czy istnieją obecnie najlepsze praktyki dotyczące używania srcset, które radzą sobie ze specyfikacjami różnych bieżących implementacji, wykorzystując możliwości tej funkcji bez powodowania pobierania zbyt dużych obrazów?

Odpowiedz

18

Ogólnie z srcset nie można przewidzieć wybranego kandydata.

Pulpit Chrome: Chrome faktycznie uruchamia bardzo dobre, ale nieprzewidywalne algorytmy, aby uzyskać odpowiedni obraz. Na przykład, jeśli jest on buforowany lub, jak powiedziałeś lokalnie, użyje największego obrazu. Tutaj wszystko powinno być w porządku.

Desktop Firefox: Wygląda na to, że sprawdzasz przy włączonym srcsecie, ale obraz jest wyłączony. srcset z atrybutem deskryptora i rozmiarów szerokości można włączyć tylko wtedy, gdy włączony jest zarówno srcset, jak i flaga obrazu. Ale sugerowałbym, żebyś testował z bieżącym FF co noc, ponieważ ta funkcja zostanie przycięta z 38, a żeby to zrobić, niektóre błędy zostały naprawione. W przeciwnym razie uzyskasz takie samo działanie, jak w przeglądarce Safari na iOS. FF38 będzie miało pożądane zachowanie.

iOS: Chrome na iOS to nie Chrome. Przeglądarka iOS nie obsługuje srcset z deskryptorem szerokości, ale obsługuje tylko deskryptor x. Co gorsza, jeśli używasz deskryptora szerokości, iOS uważa, że ​​wszyscy kandydaci są równi (1x) i załaduje pierwszego kandydata z listy srcset.

Oto jak można radzić sobie ze wszystkimi problemami:

  1. użyć dobrego PolyFill: respimage lub picturefill wykonać zadanie
  2. Nawet jeśli nie używasz kierunek sztuki użyć następującego wzoru:

<picture> <source srcset="images/image-1920.jpg 1920w, images/image-1440.jpg 1440w, images/image-1152.jpg 1152w, images/image-960.jpg 960w, images/image-840.jpg 840w, images/image-720.jpg 720w, images/image-576.jpg 576w, images/image-420.jpg 420w, images/image-288.jpg 288w, images/image-144.jpg 144w" sizes="(min-width: 40em) 576px, (min-width: 64em) 720px, (min-width: 72em) 960px, 100vw" /> <img /> </picture>

Jeśli chcesz mieć większą kontrolę można też użyć lazySizes, która pozwala wyliczyć automatyczne wyliczanie z pudełka, a jeśli chcesz ograniczyć współczynnik pikseli w przeglądarkach mobilnych (na przykład 1,6x zamiast 2x), optimumx plugin.

wtedy mógłby napisać znaczników tak:

<picture> <source data-srcset="images/image-1920.jpg 1920w, images/image-1440.jpg 1440w, images/image-1152.jpg 1152w, images/image-960.jpg 960w, images/image-840.jpg 840w, images/image-720.jpg 720w, images/image-576.jpg 576w, images/image-420.jpg 420w, images/image-288.jpg 288w, images/image-144.jpg 144w" /> <img class="lazyload" data-sizes="auto" data-optimumx="1.6" /> </picture>

+0

to nie moja sprawa, ale szukając o problemie z class = „img reagujący” w bootstrap z srcset. Okazało się, że to "rozmiary =" (min-szerokość: 40em) 576px, (min-szerokość: 64em) 720px, (min-szerokość: 72em) 960px, 100vw "" rozwiązać mój problem. Dzięki! – Equiman

Powiązane problemy