Untuk memprediksi kandidat gambar responsif, tentukan lebar CSS dari sizes, kalikan dengan rasio piksel perangkat, lalu bandingkan hasilnya dengan srcset. Kemudian verifikasi URL yang dipilih: browser tetap memiliki keleluasaan dalam menentukan pilihan akhir.

Panduan ini ditujukan bagi orang yang memeriksa halaman web yang dibuat sendiri di Chrome pada Mac. Anda akan menghitung kandidat yang mungkin dipilih, menguji halaman lokal yang berisi bentuk abstrak orisinal, dan membedakan deklarasi ukuran yang menyesatkan dari perilaku pemilihan browser yang normal.

Apa yang diberitahukan oleh sizes, srcset, dan DPR kepada browser?

Dengan deskriptor lebar, srcset mencantumkan sumber daya yang tersedia beserta lebar piksel intrinsiknya. Deskriptor seperti 800w harus menggambarkan gambar yang lebarnya memang 800 piksel. Pisahkan deskriptor lebar dan deskriptor kepadatan seperti 2x ke dalam set sumber yang berbeda; mencampurnya dalam satu srcset tidak valid. Referensi elemen gambar MDN menjelaskan persyaratan ini.

sizes memberikan lebar tampilan yang dimaksudkan untuk pemilihan sumber daya. Browser mengevaluasi kondisinya secara berurutan dan menggunakan entri pertama yang cocok. Letakkan nilai cadangan tanpa syarat di urutan terakhir. Ukuran sumber menerima nilai panjang seperti 480px, 50vw, dan calc(100vw - 32px); nilai persentase seperti 50% bukan lebar slot yang valid. Menggunakan gambar responsif dalam HTML

CSS mengontrol dimensi tampilan. Perlakukan CSS dan daftar sizes eksplisit sebagai dua deskripsi yang harus tetap selaras: satu menentukan tata letak, sedangkan yang lain memberi informasi untuk pemilihan sumber daya. Mengubah sizes saja tidak menerapkan tata letak yang sesuai. Standar HTML: Atribut Sizes

DPR menjelaskan hubungan antara piksel fisik dan piksel CSS. Baca window.devicePixelRatio alih-alih mengasumsikan nilainya berdasarkan model Mac atau nama layar. Zoom halaman dapat mengubah nilai ini, begitu pula memindahkan jendela antar layar. Zoom cubit tidak mengubah DPR. MDN: Window.devicePixelRatio

Bagaimana cara menghitung kandidat yang mungkin dipilih?

Untuk ukuran sumber yang ditentukan S, lebar sumber daya W, dan DPR D, gunakan dua perhitungan berikut yang setara:

Lebar sumber daya target = S × D
Kepadatan efektif kandidat = W ÷ S

Model pemrosesan HTML menormalisasi deskriptor lebar dengan membagi lebar setiap kandidat dengan ukuran sumber. MDN juga menjelaskan prediksi praktisnya sebagai perkalian petunjuk ukuran dengan DPR. Standar HTML: Menormalisasi kepadatan sumber, MDN: HTMLImageElement.sizes

Untuk perkiraan praktis, pilih kandidat terkecil yang sama dengan atau lebih besar daripada lebar target. Jika semua kandidat lebih kecil daripada target, tentukan kandidat terbesar yang tersedia dan catat kekurangannya. Ini adalah aturan prediksi eksplisit untuk latihan di bawah. Standar HTML menyerahkan pemilihan akhir kepada implementasi; standar tersebut tidak mengharuskan setiap browser mengikuti aturan pembulatan ini. Standar HTML: Memilih sumber gambar

Perhatikan daftar ukuran sumber berikut, yang dipasangkan dengan kandidat 480w, 800w, 1200w, dan 1440w:

(max-width: 600px) calc(100vw - 32px),
(max-width: 1200px) calc(50vw - 32px),
568px

100vw mewakili lebar viewport dan 50vw mewakili setengah lebar tersebut. Unit ini merujuk pada viewport, bukan kontainer induk gambar. Nilai dan Unit CSS: Panjang persentase viewport

Tabel berikut berisi perhitungan ilustratif, bukan hasil yang direkam dari browser. Kolom terakhir menerapkan aturan prediksi yang telah dijelaskan.

Lebar viewport, px CSS DPR Ukuran sumber yang ditentukan, px CSS Lebar sumber daya target, px Kandidat yang diprediksi
600 1 568 568 800w
600 2 568 1,136 1200w
601 2 268.5 537 800w
1,000 1 468 468 480w
1,000 2 468 936 1200w
1,400 2 568 1,136 1200w
1,400 3 568 1,704 1440w, di bawah target

Peralihan dari 600 ke 601 piksel CSS sangat berguna untuk diuji. Pada 600, kondisi pertama menghasilkan slot yang hampir selebar viewport. Pada 601, kondisi kedua menghasilkan slot yang jauh lebih sempit. Karena itu, viewport yang lebih lebar menghasilkan gambar target yang lebih kecil. Hal tersebut langsung mengikuti kontrak tata letak yang dibuat ini.

Pada viewport 1.000 piksel dan DPR 2, ukuran sumbernya adalah 468 piksel CSS. Keempat kandidat memiliki kepadatan efektif sekitar 1.03x, 1.71x, 2.56x, dan 3.08x. Berdasarkan aturan prediksi kita, kandidat 1200w adalah yang pertama melampaui kepadatan target 2x.

Bagaimana cara membuat pengujian lokal yang lengkap?

Gunakan Mac dengan Chrome dan Python 3.8 atau yang lebih baru. Simpan program lengkap berikut sebagai responsive_demo.py di editor teks biasa. Program ini membuat empat file PNG yang masing-masing berisi persegi panjang dan lingkaran yang sama, menulis halaman yang sesuai, lalu menjalankan server lokal. Semua file yang dihasilkan disimpan dalam direktori sementara baru, sehingga file yang sudah ada tidak tertimpa.

Halaman ini sengaja menggunakan gambar eager dan ukuran sumber eksplisit. Lebar CSS-nya cocok dengan tiga cabang yang digunakan dalam tabel perhitungan. Server menggunakan ThreadingHTTPServer dan handler permintaan berbasis direktori yang terdokumentasi oleh Python. Python: http.server

from functools import partial
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
from pathlib import Path
import struct
import tempfile
import zlib


def chunk(kind, data):
    return (
        struct.pack("!I", len(data)) + kind + data
        + struct.pack("!I", zlib.crc32(kind + data))
    )


def make_png(width):
    height = width // 2
    rows = []
    for y in range(height):
        row = bytearray()
        for x in range(width):
            color = (242, 244, 248)
            if width // 8 <= x < width // 2 and height // 4 <= y < 3 * height // 4:
                color = (70, 100, 160)
            if (x - 3 * width // 4) ** 2 + (y - height // 2) ** 2 < (height // 5) ** 2:
                color = (220, 160, 60)
            row.extend(color)
        rows.append(b"\x00" + row)
    header = struct.pack("!IIBBBBB", width, height, 8, 2, 0, 0, 0)
    return (
        b"\x89PNG\r\n\x1a\n"
        + chunk(b"IHDR", header)
        + chunk(b"IDAT", zlib.compress(b"".join(rows)))
        + chunk(b"IEND", b"")
    )


page = '''<!doctype html>
<html lang="en">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Shape A candidate test</title>
<style>
  body { margin: 0; padding: 16px; font-family: sans-serif; }
  #shape { display: block; width: calc(100vw - 32px); height: auto; }
  @media (min-width: 600.01px) {
    #shape { width: calc(50vw - 32px); }
  }
  @media (min-width: 1200.01px) {
    #shape { width: 568px; }
  }
</style>
<p>Shape A: rectangle and circle</p>
<img id="shape" src="shape-a-800.png" width="1440" height="720"
     alt="Blue rectangle and amber circle on a pale background"
     srcset="shape-a-480.png 480w, shape-a-800.png 800w,
             shape-a-1200.png 1200w, shape-a-1440.png 1440w"
     sizes="(max-width: 600px) calc(100vw - 32px),
            (max-width: 1200px) calc(50vw - 32px), 568px">
</html>
'''

root = Path(tempfile.mkdtemp(prefix="responsive-shapes-"))
for width in (480, 800, 1200, 1440):
    (root / f"shape-a-{width}.png").write_bytes(make_png(width))
(root / "index.html").write_text(page, encoding="utf-8")
handler = partial(SimpleHTTPRequestHandler, directory=str(root))
with ThreadingHTTPServer(("127.0.0.1", 0), handler) as server:
    print(f"Files: {root}", flush=True)
    print(f"Open http://127.0.0.1:{server.server_port}/", flush=True)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        pass

Di Terminal, pindah ke folder tempat Anda menyimpan program, lalu jalankan:

python3 responsive_demo.py

Buka alamat lokal yang dicetak program di Chrome. Biarkan Terminal tetap berjalan selama pengujian; tekan Control+C di sana setelah selesai. Program meminta port yang tersedia, jadi gunakan alamat yang dicetaknya alih-alih mengasumsikan nomor port tertentu.

Ambang CSS menggunakan 600.01px dan 1200.01px untuk lebar viewport bilangan bulat dalam pengujian desktop. Uji nilai bilangan bulat yang tepat pada tabel. Saat menyesuaikan contoh ini dengan tata letak produksi, selaraskan breakpoint CSS yang sebenarnya dengan kondisi ukuran sumber, termasuk perilaku lebar pecahan.

Bagaimana cara memverifikasi pemilihan di Chrome pada Mac?

Klik kanan bentuk tersebut dan pilih Inspect untuk membuka DevTools dengan elemen gambarnya terpilih. Chrome mendokumentasikan cara ini sebagai metode langsung untuk memeriksa elemen dan gaya yang diterapkan padanya. Buka Chrome DevTools

  1. Klik Toggle device toolbar, lalu pilih Responsive di bagian Dimensions.
  2. Atur lebar viewport ke 1000.
  3. Di menu More options pada toolbar, pilih Add device pixel ratio, lalu pilih DPR 2.
  4. Jika perlu, pilih More options, lalu Add device type, dan pilih Desktop.
  5. Buka Network, aktifkan Disable cache, lalu muat ulang halaman dengan DevTools terbuka.
  6. Temukan gambar yang diminta dengan memfilter shape-a.

Chrome mendokumentasikan kontrol viewport, DPR, dan jenis perangkat dalam Panduan Device Mode, serta kontrol cache dalam Referensi fitur Network.

Setelah halaman dimuat, jalankan cuplikan diagnostik lengkap ini di Console DevTools:

(() => {
  const image = document.getElementById("shape");
  if (!image) throw new Error("The Shape A image was not found.");

  const viewport = window.innerWidth;
  const slot = window.matchMedia("(max-width: 600px)").matches
    ? viewport - 32
    : window.matchMedia("(max-width: 1200px)").matches
      ? viewport / 2 - 32
      : 568;

  console.table({
    viewportCSSPixels: viewport,
    devicePixelRatio: window.devicePixelRatio,
    declaredSlotCSSPixels: slot,
    renderedWidthCSSPixels: image.getBoundingClientRect().width,
    targetResourcePixels: slot * window.devicePixelRatio,
    selectedURL: image.currentSrc,
    naturalWidthCSSPixels: image.naturalWidth
  });
})();

Cuplikan ini menghitung slot yang dideklarasikan khusus untuk demo ini; cuplikan ini bukan parser sizes umum. Bandingkan slot yang dideklarasikan dengan lebar hasil render, lalu bandingkan nama file yang dipilih dengan tabel prediksi.

currentSrc melaporkan URL lengkap yang dipilih browser. Nilai ini tidak membuktikan bahwa sumber daya berhasil dimuat, jadi periksa juga permintaan gambar dan hasil yang ditampilkan. Membaca src hanya akan menampilkan atribut fallback dalam contoh ini. MDN: HTMLImageElement.currentSrc

Jangan mengartikan naturalWidth sebagai lebar PNG yang dikodekan. Nilainya adalah lebar yang telah dikoreksi berdasarkan kepadatan dalam piksel CSS. Untuk fixture terkontrol ini, dimensi file yang dihasilkan dan nama filenya menunjukkan lebar sumber daya. MDN: HTMLImageElement.naturalWidth

Ulangi pengujian pada 600 dan 601 piksel CSS, lalu muat ulang untuk setiap kondisi. Catat viewport, DPR yang dilaporkan, slot, nama file yang dipilih, dan apakah permintaannya selesai. Catatan ini membedakan hasil pemuatan baru yang berulang dari rangkaian pilihan yang dibuat saat mengubah ukuran halaman yang sudah dimuat.

Apa yang perlu diperiksa jika prediksi berbeda?

Periksa masukan satu per satu sebelum mengubah daftar kandidat:

  1. Periksa jenis deskriptor. Untuk deskriptor kepadatan seperti 1x dan 2x, jangan gunakan perhitungan deskriptor lebar melalui sizes.
  2. Periksa kondisi pertama yang cocok. Kondisi lebih awal yang cocok diutamakan daripada entri berikutnya.
  3. Bandingkan lebar yang dideklarasikan dan yang dirender. Deklarasi 100vw dapat melebih-lebihkan slot yang dibatasi CSS menjadi kolom sempit.
  4. Baca DPR yang sebenarnya. Periksa kembali setelah zoom halaman atau perubahan layar.
  5. Bandingkan pemuatan ulang yang terkontrol. Pertahankan viewport, DPR, dan kondisi pemuatan yang sama saat mengulangi pengujian.
  6. Periksa ketersediaan sumber daya. URL yang dipilih dan gambar yang berhasil ditampilkan adalah dua pengamatan terpisah.

Ukuran sumber eksplisit yang tidak ada atau tidak dapat digunakan dapat menyebabkan parser HTML memakai nilai default 100vw. Hal itu dapat menjelaskan target yang sangat besar untuk gambar yang sempit. Berikan daftar ukuran sumber yang akurat alih-alih menganggap browser akan menyimpulkan lebar kolom yang dimaksud dari CSS Anda. Standar HTML: Mengurai atribut sizes

Jika halaman menggunakan elemen picture, tentukan cabang sumber yang berlaku sebelum menghitung kepadatan. Pemilihan sumber tersebut dilakukan sebelum pilihan di antara kandidat pada cabang itu; crop yang berbeda termasuk dalam mekanisme pengarahan seni ini. Menggunakan gambar responsif dalam HTML

Batas dukungan apa yang memengaruhi metode ini?

MDN menandai properti sizes sebagai tersedia secara luas di berbagai browser, tetapi itu tidak berarti setiap kata kunci yang lebih baru didukung secara setara. Kondisi eksplisit yang digunakan di sini memberikan pengujian langsung tanpa mengandalkan ukuran otomatis. MDN: HTMLImageElement.sizes

sizes="auto" valid untuk gambar yang dimuat secara lazy dan memungkinkan pemilihan menggunakan lebar tata letaknya. Jika Anda menggunakannya, pertahankan ukuran fallback eksplisit setelah auto untuk browser yang tidak mendukung kata kunci tersebut, dan sediakan dimensi gambar. Jangan menggantinya dalam contoh pemuatan eager ini tanpa mengubah prasyarat tersebut. Referensi elemen gambar MDN

Kontrol perangkat Chrome menguji perilaku Chrome dalam kondisi emulasi. Kontrol tersebut tidak menunjukkan pilihan kandidat di Safari atau Firefox. Chrome juga menjelaskan bahwa Device Mode hanyalah pendekatan, jadi uji langsung di browser lain jika perilaku browser tersebut penting. Chrome DevTools: Batasan Device Mode

Prediksi yang berguna diakhiri dengan catatan yang dapat diperiksa: set sumber yang berlaku, ukuran sumber yang ditentukan, DPR yang dilaporkan, target hasil perhitungan, dan currentSrc yang diamati. Jika masukan tersebut sesuai dengan tata letak yang dibuat, Anda dapat menjelaskan pilihan sumber daya dengan jelas dan menentukan apakah perubahan berikutnya perlu dilakukan pada CSS, sizes, atau lebar gambar yang tersedia.

Sumber