Foto hero berukuran 1200 piksel terlihat bagus di desktop, tetapi pengunjung ponsel dengan layar 360 piksel tetap mengunduh seluruh 1200 pikselnya — membayar kuota untuk piksel yang tidak pernah tampil. Ukuran berkas membesar mengikuti dimensi gambar, dan CSS bisa mengecilkan tampilan gambar, tetapi tidak bisa mengecilkan jumlah byte yang dikirim. Solusinya: menyediakan beberapa versi berkas dan membiarkan browser memilih yang paling pas.

Masalah: Satu File untuk Semua Layar #

Mekanisme masalahnya begini: ponsel dan desktop membutuhkan jumlah piksel yang berbeda untuk gambar yang tampak sama bagusnya, ditambah device pixel ratio — ponsel modern menampilkan 2-3 piksel perangkat untuk setiap piksel CSS. Satu berkas besar untuk semua berarti berkas itu selalu berlebihan bagi sebagian pengunjung, dan terlalu kecil bagi sebagian yang lain.

Atribut srcset #

Aturannya: srcset berisi daftar kandidat yang dipisah koma — nama berkas diikuti deskriptor lebar, misalnya 480w, 800w, 1200w. Deskriptor 480w menyatakan berkas itu selebar 480 piksel secara asli. Angka ini adalah ukuran berkas, bukan ukuran tampilan di halaman.

Atribut sizes #

Aturannya: sizes memberi petunjuk lebar tampilan gambar per kondisi media. Nilainya satu atau lebih pasangan (kondisi media) lebar, diakhiri satu lebar tanpa kondisi sebagai keadaan sisa. Browser mengalikan lebar tampilan itu dengan device pixel ratio layar, lalu memilih kandidat terkecil yang memenuhi kebutuhan.

Contoh Lengkap #

html
<img
  src="assets/hero-800.jpg"
  alt="Barista Kedai Kopi Siti menuangkan kopi susu gula aren"
  width="800"
  height="533"
  srcset="assets/hero-480.jpg 480w,
          assets/hero-800.jpg 800w,
          assets/hero-1200.jpg 1200w"
  sizes="(max-width: 600px) 100vw, 800px">

Mari kita bedah bagian per bagian:

  1. src="assets/hero-800.jpg": kandidat cadangan — dipakai browser lama yang tidak memahami srcset, sekaligus alamat utamanya.
  2. alt, width, height: tetap berlaku seperti biasa — rasio 800:533 tetap tercadang sejak parsing.
  3. srcset kandidat 480w: berkas hero-480.jpg selebar 480 piksel asli — kandidat paling ringan.
  4. Kandidat 800w dan 1200w: dua varian lebih besar untuk layar lebih lebar atau lebih padat piksel.
  5. sizes — (max-width: 600px) 100vw: bila viewport selebar maksimal 600 piksel, gambar ditampilkan selebar penuh viewport.
  6. sizes — nilai akhir 800px: untuk viewport yang lebih lebar, gambar tampil selebar 800 piksel di halaman.
  7. Keputusan browser: ponsel 360 piksel dengan device pixel ratio 2 membutuhkan sekitar 720 piksel, jadi browser memuat hero-800.jpg; desktop dengan lebar tampil 800 piksel dan rasio 1 juga memuat hero-800.jpg; hanya perangkat yang lebih besar dan lebih padat yang mengambil hero-1200.jpg.

Kandidat mana yang dipilih browser-mu? Label warna pada gambar berikut menunjukkan kandidat yang sedang dimuat — sempitkan jendela browser lalu muat ulang halaman, dan lihat pilihannya berubah:

Pada demo, ketiga berkas kandidat diganti placeholder SVG berlabel dan berwarna berbeda agar pilihan browser langsung terlihat; pada berkas sungguhan, ketiganya versi foto yang sama dengan lebar berbeda. Perangkat dengan layar padat piksel (device pixel ratio tinggi) memilih kandidat lebih besar meski lebar tampilnya sama — label yang tampil di layarmu itulah keputusan browser-mu saat ini.

Siapa yang Memilih #

Kita menyediakan kandidat dan petunjuk; browser yang memutuskan saat halaman dimuat — bukan server, bukan CSS. Browser mengetahui tiga hal yang tidak tertulis di markup: lebar viewport nyata, kepadatan piksel perangkat, dan (pada sebagian implementasi) kondisi jaringan. Tugas kita satu: memastikan daftar kandidatnya jujur — deskriptor 480w harus benar-benar berisi berkas selebar 480 piksel.

Ringkasan #

  • Satu berkas untuk semua layar berlebihan bagi sebagian pengunjung; sediakan beberapa lebar.
  • srcset mendata kandidat dengan deskriptor lebar asli berkasnya (480w, 800w, 1200w).
  • sizes memberi petunjuk lebar tampil per kondisi media; tanpa sizes browser memakai lebar penuh viewport.
  • Pemilihan kandidat dilakukan browser — bukan server, bukan CSS.

srcset menyerahkan keputusan piksel kepada browser; ketika kita ingin memutuskan sendiri kondisi dan formatnya, chapter berikutnya membahas picture.