Satu berkas gambar untuk semua perangkat memaksa ponsel mengunduh gambar berukuran desktop, atau sebaliknya memaksakan gambar buram pada layar besar. Topik ini membahas atribut srcset dengan deskriptor lebar dan kerapatan, atribut sizes yang memberi tahu ukuran slot tampil, serta elemen picture untuk art direction dan format modern. Setelah mengikuti topik ini, markup gambar yang menyesuaikan diri dengan layar dan kebutuhan piksel dapat disusun.
Masalah satu berkas untuk semua layar#
Penskalaan melalui CSS hanya mengubah ukuran tampil, bukan ukuran berkas yang diunduh. Gambar 1280 piksel yang dipersempit menjadi 320 piksel di layar ponsel tetap membawa seluruh datanya, sehingga ponsel membayar kuota untuk piksel yang tidak pernah terlihat jelas. Arah sebaliknya juga bermasalah, karena gambar kecil yang direnggangkan di layar besar tampak buram.
Beban itu berulang pada setiap kunjungan, karena gambar termasuk aset yang jarang berubah tetapi selalu diminta. Dengan beberapa kandidat berkas gambar, layar kecil membawa berkas yang jauh lebih ringan, sedangkan layar besar tetap menerima versi yang tajam. Efeknya langsung terasa pada kecepatan tampil halaman dan pada kuota yang terpakai.
Kebutuhan piksel juga bukan sekadar lebar slotnya. Layar dengan kerapatan tinggi (device pixel ratio 2) menampilkan slot selebar 400 piksel CSS dengan 800 piksel gambar agar tetap tajam, dan kerapatan 3 menuntut 1200 piksel. Satu berkas tidak mungkin pas untuk semua kombinasi lebar layar dan kerapatan tersebut, sehingga browser perlu diberi beberapa kandidat beserta petunjuk pemilihannya. Dua atribut berikutnya, srcset dan sizes, adalah sarana untuk itu, sedangkan elemen picture menangani kasus yang lebih mendasar ketika komposisi gambarnya sendiri perlu diganti.
srcset dengan deskriptor lebar#
Atribut srcset mendaftar kandidat berkas beserta deskriptor lebar (width descriptor), yaitu angka berakhiran w yang menyatakan lebar asli setiap berkas dalam piksel. Nilai src tetap ditulis sebagai cadangan bagi browser lama yang tidak mengenal srcset. Kandidat pada contoh berikut tersedia dalam tiga lebar, dan tampilannya menggunakan gambar suasana ruang baca.
<img
src="suasana-640.svg"
srcset="suasana-320.svg 320w, suasana-640.svg 640w, suasana-1280.svg 1280w"
sizes="(max-width: 600px) 480px, 800px"
alt="Suasana ruang baca dengan meja, buku, dan lampu"
width="1280" height="720">Satu kandidatnya berupa berkas berikut. Dua berkas lainnya disusun dengan pola yang sama, yaitu viewBox dan lebar deklarasi 640 serta 1280 piksel, dengan bentuk-bentuk yang lebih rinci pada versi yang lebih besar.
<svg xmlns="http://www.w3.org/2000/svg" width="320" height="180" viewBox="0 0 320 180" role="img" aria-labelledby="judul-320">
<title id="judul-320">Suasana ruang baca, versi sederhana 320 piksel</title>
<rect width="320" height="180" fill="#e3f2fd"/>
<rect y="130" width="320" height="50" fill="#a1887f"/>
<rect x="60" y="92" width="200" height="38" rx="5" fill="#8d6e63"/>
<rect x="92" y="62" width="58" height="32" rx="3" fill="#ffffff" stroke="#90a4ae"/>
<circle cx="244" cy="52" r="15" fill="#fff59d" stroke="#f9a825" stroke-width="3"/>
</svg>Deskriptor w wajib menyatakan lebar asli berkas dengan benar, karena angka itulah yang dibandingkan browser dengan kebutuhan pikselnya. Apabila srcset menggunakan deskriptor w, atribut sizes menjadi wajib menyertainya, sebagaimana diuraikan pada bagian berikut.
Urutan kandidat pada srcset tidak menentukan hasilnya, karena browser mengurutkannya sendiri menurut kebutuhan yang dihitung. Browser juga bebas menyimpang dari pilihan matematisnya, misalnya menggunakan kandidat yang sudah tersimpan dalam cache atau menghemat kuota, sehingga hasilnya dapat berbeda antarbrowser. Selama setiap kandidat membawa deskriptor yang benar, penyimpangan semacam itu tetap menghasilkan gambar yang layak tampil.
Cara browser memilih kandidat#
Atribut sizes memberi tahu lebar slot yang akan ditempati gambar, sehingga browser dapat menghitung kebutuhan piksel sebelum mengunduh apa pun. Nilainya berupa daftar kondisi media beserta lebar slotnya, dan kondisi pertama yang cocok yang digunakan. Browser kemudian mengalikan lebar slot itu dengan kerapatan perangkat, lalu memilih kandidat srcset terkecil yang memenuhi kebutuhan tersebut. Diagram berikut merangkum alurnya.
Simulasi berikut menjalankan alur yang sama tanpa browser, dengan lebar layar 420 piksel CSS dan kerapatan 2, sehingga hasil pemilihannya dapat diperiksa angka demi angka.
// simulasi pemilihan kandidat srcset oleh browser
const kandidat = [320, 640, 1280];
const dpr = 2;
const lebarLayar = 420; // piksel CSS pada layar yang dipakai
const sizes = "(max-width: 600px) 480px, 800px";
// lebar slot mengikuti kondisi media pertama yang cocok pada sizes
const slot = lebarLayar <= 600 ? 480 : 800;
// kebutuhan piksel adalah lebar slot dikalikan kerapatan perangkat
const kebutuhan = slot * dpr;
// kandidat terkecil yang memenuhi kebutuhan, atau kandidat terbesar
let dipilih = kandidat[kandidat.length - 1];
for (const k of kandidat) {
if (k >= kebutuhan) {
dipilih = k;
break;
}
}
console.log(`lebar layar: ${lebarLayar} piksel CSS`);
console.log(`slot tampil: ${slot} piksel CSS`);
console.log(`kebutuhan piksel: ${kebutuhan} piksel`);
console.log(`kandidat terpilih: ${dipilih}w`);lebar layar: 420 piksel CSS
slot tampil: 480 piksel CSS
kebutuhan piksel: 960 piksel
kandidat terpilih: 1280wKeluaran memperlihatkan kasus yang wajar, yaitu kandidat 640w tidak cukup besar untuk kebutuhan 960 piksel, sehingga browser memilih 1280w. Tanpa sizes, browser mengasumsikan slot selebar seluruh layar (viewport), sehingga gambarnya cenderung diunduh lebih besar dari yang diperlukan.
Selain deskriptor w, srcset juga menerima deskriptor kerapatan (density descriptor) berakhiran x, misalnya logo.svg 1x, logo-2x.svg 2x. Bentuk ini cocok untuk gambar yang ukuran slotnya tetap, karena browser cukup membandingkannya dengan kerapatan perangkat tanpa membaca sizes.
picture untuk art direction#
Atribut srcset dan sizes hanya mengganti berkas dengan kandungan gambar yang sama, sedangkan art direction menuntut komposisi yang berbeda, misalnya potongan rapat untuk layar sempit dan tampilan lebar untuk layar besar. Elemen picture menyelesaikannya dengan menyediakan beberapa elemen source yang masing-masing membawa kondisi media dan kandidatnya, disusul satu elemen img wajib sebagai isi yang dirender.
<picture>
<source media="(max-width: 600px)" srcset="potongan-kecil.svg">
<img src="potongan-lebar.svg"
alt="Papan pengumuman pada dinding, tampilan lebar"
width="800" height="400">
</picture><svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400" role="img" aria-labelledby="judul-potongan-kecil">
<title id="judul-potongan-kecil">Potongan rapat papan pengumuman untuk layar sempit</title>
<rect width="400" height="400" fill="#f5f5f4"/>
<rect x="40" y="40" width="320" height="320" rx="10" fill="#d6c39a" stroke="#8d6e63" stroke-width="8"/>
<rect x="80" y="90" width="240" height="60" rx="6" fill="#ffffff"/>
<rect x="80" y="180" width="240" height="60" rx="6" fill="#ffffff"/>
<rect x="80" y="270" width="180" height="60" rx="6" fill="#ffffff"/>
</svg><svg xmlns="http://www.w3.org/2000/svg" width="800" height="400" viewBox="0 0 800 400" role="img" aria-labelledby="judul-potongan-lebar">
<title id="judul-potongan-lebar">Tampilan lebar papan pengumuman pada dinding untuk layar lebar</title>
<rect width="800" height="400" fill="#f5f5f4"/>
<rect y="330" width="800" height="70" fill="#a1887f"/>
<rect x="280" y="80" width="240" height="180" rx="8" fill="#d6c39a" stroke="#8d6e63" stroke-width="6"/>
<rect x="300" y="110" width="200" height="34" rx="4" fill="#ffffff"/>
<rect x="300" y="160" width="200" height="34" rx="4" fill="#ffffff"/>
<rect x="80" y="120" width="120" height="140" rx="8" fill="#b0bec5"/>
<rect x="620" y="150" width="120" height="110" rx="8" fill="#b0bec5"/>
</svg>Browser menggunakan source pertama yang kondisinya cocok, sehingga urutannya harus dari yang paling khusus menuju yang paling umum. Elemen img di bagian akhir bukan opsional, melainkan satu-satunya elemen yang benar-benar dirender, dan sekaligus menjadi cadangan bagi browser yang tidak mengenal picture. Atribut alt, width, dan height milik img itulah yang berlaku, sehingga teks penggantinya perlu mendeskripsikan gambar yang paling mungkin tampil.
<picture>
<source type="image/avif" srcset="foto.avif">
<source type="image/webp" srcset="foto.webp">
<img src="foto.jpg" alt="Ruang baca perpustakaan" width="1280" height="720">
</picture>Contoh berkas utuh#
Berkas berikut menyatukan dua pola pada satu halaman, yaitu peralihan resolusi dengan srcset dan sizes pada gambar pertama, serta art direction dengan picture pada gambar kedua. Simpan berkas itu bersama suasana-320.svg, suasana-640.svg, suasana-1280.svg, potongan-kecil.svg, dan potongan-lebar.svg dalam satu folder, lalu bukanya di browser dan ubah lebar jendelanya. Gambar pertama berpindah kandidat secara halus, sedangkan gambar kedua berpindah komposisi pada titik 600 piksel.
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Galeri gambar responsif</title>
<style>
body { font-family: sans-serif; max-width: 52rem; margin: 0 auto; padding: 0 1rem; }
img { max-width: 100%; height: auto; }
</style>
</head>
<body>
<h1>Galeri gambar responsif</h1>
<h2>Peralihan resolusi dengan srcset</h2>
<img
src="suasana-640.svg"
srcset="suasana-320.svg 320w, suasana-640.svg 640w, suasana-1280.svg 1280w"
sizes="(max-width: 600px) 480px, 800px"
alt="Suasana ruang baca dengan meja, buku, dan lampu"
width="1280" height="720">
<h2>Pengarahan seni dengan picture</h2>
<picture>
<source media="(max-width: 600px)" srcset="potongan-kecil.svg">
<img src="potongan-lebar.svg"
alt="Papan pengumuman pada dinding, tampilan lebar"
width="800" height="400">
</picture>
</body>
</html>Kandidat pada contoh ini berupa berkas SVG kecil agar seluruh asetnya dapat diperiksa, sedangkan pada praktiknya kandidat yang sama berlaku untuk berkas JPEG, WebP, atau AVIF dengan lebar yang dinyatakan oleh deskriptornya. Lebar jendela dapat diubah perlahan untuk mengamati perpindahan kandidat, dan alat simulasi perangkat pada DevTools mempercepat pengujian ukuran tertentu. Tab jaringan pada DevTools juga memperlihatkan berkas mana yang benar-benar diunduh pada setiap lebar. Yang berpindah di balik layar hanyalah pilihan berkas, sedangkan markup di halaman tidak pernah berubah.
Kesalahan umum#
Menggunakan deskriptor w tanpa sizes. Browser mengasumsikan gambar menempati seluruh lebar layar dan mengunduh kandidat yang terlalu besar. Lengkapi srcset berdeskriptor w dengan sizes yang menggambarkan slot tampilnya.
Deskriptor w tidak sesuai lebar asli berkas. Perbandingan kebutuhan piksel dengan kandidat menjadi keliru, sehingga gambar buram atau kandidat yang diunduh berlebihan. Catat lebar asli setiap berkas dan tuliskan dengan benar pada deskriptornya.
Menyusun source dalam urutan yang salah. Browser menggunakan kondisi pertama yang cocok, sehingga source yang paling umum yang ditulis lebih dahulu akan selalu menutup kandidat di bawahnya. Susun dari yang paling khusus, dan biarkan img sebagai penutup.
Menyingkirkan elemen img dari picture. Elemen itu bukan cadangan yang boleh hilang, melainkan satu-satunya yang dirender, sehingga picture tanpa img tidak menampilkan apa pun dan tidak sah. Selalu tutup picture dengan satu img lengkap beserta alt-nya.
Menggunakan picture untuk sekadar mengganti resolusi. Bila kandungan gambarnya sama dan hanya ketajamannya yang berbeda, srcset dengan sizes sudah cukup dan markupnya lebih pendek. Simpan picture untuk pergantian komposisi dan pergantian format.
Ringkasan#
srcsetdengan deskriptorwmendaftar kandidat berdasarkan lebar aslinya, dansizesmenyatakan lebar slot agar browser dapat menghitung kebutuhan pikselnya.- Browser memilih kandidat terkecil yang lebar setidaknya sama dengan lebar slot dikalikan kerapatan perangkat, dan mengasumsikan seluruh lebar layar bila
sizestidak ada. - Deskriptor
xmembandingkan kandidat langsung dengan kerapatan perangkat dan tidak memerlukansizes. - Elemen
picturemengganti komposisi melaluisourceberkondisi media serta format melaluisourcebertipe, denganimgsebagai elemen yang dirender dan sekaligus cadangannya.
Referensi#
- Responsive images — MDN Web Docs — Panduan lengkap srcset, sizes, dan picture beserta penggunaannya.
- Elemen picture — MDN Web Docs — Dokumentasi elemen picture beserta elemen source di dalamnya.
- Responsive images — web.dev — Pelajaran gambar responsif pada kursus Learn Images web.dev.
- Images — HTML Living Standard — WHATWG — Spesifikasi resmi pemilihan sumber gambar oleh browser.