Responsive images artinya menyediakan beberapa versi dari gambar yang sama, lalu membiarkan browser memilih yang paling pas untuk layar pengunjung. HP kecil dapat file kecil, laptop dengan layar tajam dapat file besar. Mirip beli kaos dari tabel ukuran S, M, L, XL: kamu tahu lebar badanmu, lalu ambil ukuran paling kecil yang masih muat. Kekecilan gak muat, kebesaran buang kain.
🧪 Tebakan cepat: HP dengan layar selebar 375 px dan DPR 2 membuka gambar yang tampil selebar layar. Ada file 480w, 800w, 1200w, dan 1600w. Browser mengambil yang mana? Tebak dulu, jawabannya ada di bagian "Cara browser memilih".
srcset dan sizes
Tiga istilah dulu:
- px di CSS adalah satuan ukuran di halaman. Layar HP biasanya selebar 360 sampai 430 px CSS.
- DPR (device pixel ratio) adalah berapa piksel fisik layar yang dipakai untuk 1 px CSS. Layar biasa DPR 1, layar HP yang tajam DPR 2 atau 3. Di console, cek dengan
window.devicePixelRatio. - vw (viewport width) adalah persen lebar layar.
100vwartinya selebar layar.
Supaya tajam, gambar selebar 375 px CSS di layar DPR 2 butuh file selebar 375 × 2 = 750 piksel. Ini gambar di Lab:
<img
src="hero-800.jpg"
srcset="hero-480.jpg 480w,
hero-800.jpg 800w,
hero-1200.jpg 1200w,
hero-1600.jpg 1600w"
sizes="(max-width: 600px) 100vw, 600px"
width="1200" height="900"
alt="Sawah di pagi hari">
srcsetadalah daftar file beserta lebar aslinya dalam piksel.800wartinya file itu lebarnya 800 piksel. Angkanya harus sama dengan ukuran file sebenarnya.sizesmemberi tahu seberapa lebar gambar akan tampil: di layar sampai 600 px, selebar layar (100vw); di layar yang lebih lebar, tetap 600 px. Browser butuh ini sebelum CSS selesai dimuat, makanya ditulis di HTML.srcadalah cadangan untuk browser yang gak kenalsrcset.widthdanheighttetap ditulis untuk rasio, supaya gak ada layout shift.
Cara browser memilih
Browser menghitung lebar tampil dari sizes, mengalikannya dengan DPR, lalu mengambil file terkecil yang cukup:
| Layar | DPR | Lebar tampil (dari sizes) |
Butuh | Dipilih |
|---|---|---|---|---|
| 375 px | 2 | 375 px | 750 piksel | hero-800.jpg, sekitar 80 KB |
| 375 px | 3 | 375 px | 1.125 piksel | hero-1200.jpg, sekitar 180 KB |
| 1280 px | 1 | 600 px | 600 piksel | hero-800.jpg, sekitar 80 KB |
| 1280 px | 2 | 600 px | 1.200 piksel | hero-1200.jpg, sekitar 180 KB |
Baris pertama itu jawaban tebakannya: butuh 750, jadi 800w.
Dua hal kecil yang Chrome lakukan (kamu bisa lihat di Lab):
- Kalau file yang sedikit di bawah kebutuhan sudah hampir cukup, Chrome kadang memilihnya. Layar 412 px DPR 2 butuh 824, dan Chrome mengambil 800w, bukan 1200w. Firefox mengambil 1200w.
- Kalau file yang lebih besar sudah pernah diunduh di halaman itu, Chrome memakainya lagi. Jendela yang dikecilkan gak bikin unduhan baru.
Tanpa sizes, browser menganggap gambarnya selebar layar (100vw). Di laptop 1280 px DPR 1, dia butuh 1.280 piksel dan mengunduh hero-1600.jpg (sekitar 320 KB) untuk kotak yang cuma 600 px. Empat kali lebih berat dari yang perlu.
Untuk gambar yang ukurannya tetap, misalnya logo selebar 200 px, cukup pakai deskriptor x: srcset="logo.png 1x, logo-2x.png 2x".
<picture>: gambar beda atau format beda
srcset cuma memilih ukuran dari gambar yang sama. Kalau yang berubah gambarnya sendiri, pakai <picture>. Browser membaca tiap <source> dari atas, mengambil yang pertama cocok, dan kalau gak ada yang cocok memakai <img> di akhir.
Art direction, potongan gambar yang berbeda per layar, misalnya foto lebar di desktop dan potongan potret di HP:
<picture>
<source media="(max-width: 600px)" srcset="hero-potret.jpg">
<img src="hero-lebar.jpg" alt="Petani di sawah">
</picture>
Pilihan format, file yang sama dalam format yang lebih hemat, untuk browser yang mendukungnya:
<picture>
<source srcset="hero.avif" type="image/avif">
<source srcset="hero.webp" type="image/webp">
<img src="hero.jpg" width="1200" height="900" alt="Foto sampul">
</picture>
type="image/avif"membuat browser yang gak kenal AVIF melewati source itu tanpa mengunduhnya. Format terbaru ditaruh paling atas.<img>di akhir wajib ada. Dialah yang benar-benar tampil, jadialt,width, danheightditulis di<img>, bukan di<source>.- Kenapa AVIF dan WebP lebih kecil dibahas di pelajaran Format Gambar Modern.
⚠️ Jebakan yang sering ketemu
- Lupa
sizes. Browser menganggap100vwdan mengunduh file kebesaran di layar lebar. sizesgak sesuai CSS. Kalau CSS-mu membuat gambar 600 px tapisizesbilang100vw, pilihannya salah. Samakan keduanya.- Ngetes cuma di laptop DPR 1. HP kebanyakan DPR 2 sampai 3, jadi butuh file yang lebih besar dari lebar layarnya.
<source>tanpatype. Browser yang gak bisa membuka AVIF tetap memilihnya, dan gambarnya rusak.<picture>tanpa<img>. Gak ada yang tampil sama sekali.
TL;DR: srcset mendaftar file beserta lebarnya (480w, 800w, 1200w, 1600w), dan sizes bilang seberapa lebar gambar tampil ((max-width: 600px) 100vw, 600px). Browser mengalikan lebar tampil dengan DPR, lalu memilih file terkecil yang cukup: layar 375 px DPR 2 butuh 750, jadi 800w. Tanpa sizes, browser menganggap 100vw dan mengunduh kebesaran. srcset untuk ukuran berbeda dari gambar yang sama. <picture> untuk gambar yang berbeda (art direction, lewat media) atau format yang berbeda (lewat type, AVIF dulu, lalu WebP), selalu dengan <img> di akhir sebagai cadangan.