{i>Syntax

Elemen <picture> tidak merender apa pun dengan sendirinya, tetapi bertindak sebagai mesin pengambil keputusan untuk elemen <img> dalam, yang memerintahkannya apa yang harus dirender. <picture> mengikuti preseden yang telah ditetapkan oleh elemen <audio> dan <video>: elemen wrapper yang berisi elemen <source> individual.

<picture>
   <source …>
   <source …>
    <img …>
</picture …>

<img> bagian dalam tersebut juga memberi Anda pola penggantian yang andal untuk browser lama tanpa dukungan gambar responsif: jika elemen <picture> tidak dikenali oleh browser pengguna, elemen tersebut akan diabaikan. Kemudian, elemen <source> juga dihapus, karena browser tidak akan mengenalinya sama sekali, atau tidak akan memiliki konteks yang berarti baginya tanpa induk <video> atau <audio>. Namun, elemen <img> bagian dalam akan dikenali oleh browser apa pun—dan sumber yang ditentukan dalam src akan dirender seperti yang diharapkan.

Gambar "Tujuan seni" dengan <picture>

Membuat perubahan pada konten atau rasio aspek gambar berdasarkan ukuran gambar di halaman biasanya disebut sebagai gambar responsif "yang ditujukan untuk seni". srcset dan sizes dirancang untuk berfungsi tanpa terlihat, menukar sumber dengan lancar saat browser pengguna memerintahkan. Namun, ada kalanya Anda ingin mengubah sumber di seluruh titik henti sementara untuk menyoroti konten dengan lebih baik, seperti saat Anda menyesuaikan tata letak halaman. Misalnya: gambar header lebar penuh dengan fokus pusat yang kecil dapat berfungsi dengan baik di area pandang yang besar:

Gambar selebar header bunga periwinkle yang dikelilingi daun dan batangnya, sedang dikunjungi oleh lebah madu.

Namun, ketika diperkecil agar sesuai dengan area pandang yang kecil, fokus utama gambar mungkin akan hilang:

Gambar lebar header bunga periwinkle, diperkecil. Lebah madu hampir tidak terlihat.

Subjek sumber gambar ini sama, tetapi untuk lebih fokus pada subjek tersebut secara visual, Anda ingin proporsi sumber gambar berubah di seluruh titik henti sementara. Misalnya, zoom yang lebih ketat di bagian tengah gambar, dan beberapa detail di tepinya terpangkas:

Tanaman bunga periwinkle yang diperbesar.

"Pemangkasan" semacam itu dapat dilakukan melalui CSS, tetapi akan membuat pengguna meminta semua data yang membentuk gambar tersebut, meskipun mereka mungkin tidak akan pernah melihatnya.

Setiap elemen source memiliki atribut yang menentukan kondisi untuk pemilihan source tersebut: media, yang menerima kueri media, dan type, yang menerima jenis media (sebelumnya dikenal sebagai "jenis MIME"). <source> pertama dalam urutan sumber yang cocok dengan konteks penjelajahan pengguna saat ini dipilih, dan konten atribut srcset pada source tersebut akan digunakan untuk menentukan kandidat yang tepat untuk konteks tersebut. Dalam contoh ini, source pertama dengan atribut media yang cocok dengan ukuran area pandang pengguna akan menjadi yang dipilih:

<picture>
  <source media="(min-width: 1200px)" srcset="wide-crop.jpg">
  <img src="close-crop.jpg" alt="…">
</picture>

Anda harus selalu menentukan img bagian dalam terakhir sesuai urutan—jika tidak ada elemen source yang cocok dengan kriteria media atau type, gambar akan bertindak sebagai sumber "default". Jika menggunakan kueri media min-width, sebaiknya Anda memiliki sumber terbesar terlebih dahulu, seperti yang terlihat pada kode sebelumnya. Saat menggunakan kueri media max-width, Anda harus menempatkan sumber terkecil terlebih dahulu.

<picture>
   <source media="(max-width: 400px)" srcset="mid-bp.jpg">
   <source media="(max-width: 800px)" srcset="high-bp.jpg">
   <img src="highest-bp.jpg" alt="…">
</picture>

Ketika sumber dipilih berdasarkan kriteria yang Anda tentukan, atribut srcset pada source akan diteruskan ke <img> seolah-olah ditetapkan pada <img> itu sendiri. Artinya, Anda juga bebas menggunakan sizes untuk mengoptimalkan sumber gambar yang diarahkan gambar album.

<picture>
   <source media="(min-width: 800px)" srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w">
   <source srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w">
   <img src="fallback.jpg" alt="…" sizes="calc(100vw - 2em)">
</picture>

Tentu saja, gambar dengan proporsi yang dapat bervariasi bergantung pada elemen <source> yang dipilih akan menimbulkan masalah performa: <img> hanya mendukung satu atribut width dan height, tetapi menghilangkan atribut tersebut dapat menyebabkan pengalaman pengguna yang jauh lebih buruk. Untuk memperhitungkan hal ini, penambahan yang relatif baru—tetapi didukung dengan baik—ke spesifikasi HTML memungkinkan penggunaan atribut height dan width pada elemen <source>. Fungsi ini berfungsi untuk mengurangi pergeseran tata letak sama baiknya seperti pada <img>, dengan ruang yang sesuai yang dicadangkan dalam tata letak untuk elemen <source> apa pun yang dipilih.

<picture>
   <source
      media="(min-width: 800px)"
      srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w"
      width="1600"
      height="800">
   <img src="fallback.jpg"
      srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w"
      sizes="calc(100vw - 2em)"
      width="1200"
      height="750"
      alt="…">
</picture>

Penting untuk diperhatikan bahwa arah gambar dapat digunakan untuk lebih dari sekadar keputusan berdasarkan ukuran area pandang—dan memang demikian, mengingat sebagian besar kasus tersebut dapat ditangani secara lebih efisien dengan srcset/sizes. Misalnya, memilih sumber gambar yang lebih cocok dengan skema warna yang ditentukan oleh preferensi pengguna:

<picture>
   <source media="(prefers-color-scheme: dark)" srcset="hero-dark.jpg">
   <img srcset="hero-light.jpg">
</picture>

Atribut type

Atribut type memungkinkan Anda menggunakan mesin keputusan permintaan tunggal elemen <picture> untuk hanya menayangkan format gambar ke browser yang mendukungnya.

Seperti yang Anda pelajari di Format dan Kompresi Gambar, encoding yang tidak dapat diurai oleh browser bahkan tidak akan dikenali sebagai data gambar.

Sebelum elemen <picture> diperkenalkan, solusi front-end yang paling tepat untuk menyajikan format gambar baru mengharuskan browser untuk meminta dan mencoba mengurai file gambar sebelum menentukan apakah akan membuangnya dan memuat penggantian. Contoh umumnya adalah skrip sepanjang baris berikut:

   <img src="image.webp"
    data-fallback="image.jpg"
    onerror="this.src=this.getAttribute('data-fallback'); this.onerror=null;"
    alt="...">

Dengan pola ini, permintaan untuk image.webp masih akan dibuat di setiap browser—yang berarti transfer yang sia-sia untuk browser tanpa dukungan untuk WebP. Browser yang kemudian tidak dapat mengurai encoding WebP akan menampilkan peristiwa onerror, dan menukar nilai data-fallback menjadi src. Itu solusi yang boros, tetapi sekali lagi, pendekatan seperti ini adalah satu-satunya pilihan yang tersedia di front-end. Ingat bahwa browser mulai membuat permintaan untuk gambar sebelum pembuatan skrip kustom memiliki kesempatan untuk dijalankan—atau bahkan diurai—sehingga kami tidak dapat menghentikan proses ini.

Elemen <picture> secara eksplisit dirancang untuk menghindari permintaan redundan. Meskipun masih tidak ada cara bagi browser untuk mengenali format yang tidak didukung tanpa memintanya, atribut type memperingatkan browser tentang encoding sumber terlebih dahulu, sehingga dapat memutuskan apakah akan membuat permintaan atau tidak.

Dalam atribut type, Anda memberikan Jenis Media (sebelumnya jenis MIME) dari sumber gambar yang ditentukan dalam atribut srcset dari setiap <source>. Hal ini memberi browser semua informasi yang diperlukan untuk segera menentukan apakah kandidat gambar yang disediakan oleh source tersebut dapat didekode tanpa membuat permintaan eksternal—jika jenis media tidak dikenali, <source> dan semua kandidatnya akan diabaikan, dan browser akan melanjutkan.

<picture>
 <source type="image/webp" srcset="pic.webp">
 <img src="pic.jpg" alt="...">
</picture>

Di sini, semua browser yang mendukung encoding WebP akan mengenali Jenis Media image/webp yang ditentukan dalam atribut type elemen <source>, memilih <source> tersebut, dan—karena kita hanya menyediakan satu kandidat di srcset—yang memerintahkan <img> bagian dalam untuk meminta, mentransfer, dan merender pic.webp. Semua browser tanpa dukungan untuk WebP akan mengabaikan source, dan tidak akan memberikan petunjuk apa pun yang sebaliknya, <img> akan merender konten src seperti yang telah dilakukan sejak tahun 1992. Anda tidak perlu menentukan elemen <source> kedua dengan type="image/jpeg" di sini, tentu saja—Anda dapat mengasumsikan dukungan universal untuk JPEG.

Terlepas dari konteks penjelajahan pengguna, semua ini dapat dilakukan dengan satu transfer file, dan tidak ada bandwidth yang terbuang untuk sumber gambar yang tidak dapat dirender. Hal ini juga berpikir maju: karena format file yang lebih baru dan lebih efisien akan disertai dengan Jenis Media sendiri, dan kami akan dapat memanfaatkannya berkat picture—tanpa JavaScript, tanpa dependensi sisi server, dan semua kecepatan <img>.

Masa depan gambar responsif

Semua pola markup yang dibahas di sini merupakan peningkatan berat dalam hal standardisasi: mengubah fungsionalitas sesuatu yang telah dikenal dan menjadi pusat web karena <img> bukanlah hal yang mudah, dan rangkaian masalah yang ingin dipecahkan oleh perubahan tersebut sangat luas. Jika Anda berpikir bahwa ada banyak hal yang perlu ditingkatkan dengan pola markup ini, Anda benar sekali. Sejak awal, standar ini dimaksudkan sebagai dasar untuk pengembangan teknologi di masa depan.

Semua solusi ini bergantung pada markup, sehingga dapat disertakan dalam payload awal dari server, dan tiba tepat waktu bagi browser untuk meminta sumber gambar—sebuah batasan yang menyebabkan atribut sizes yang memang berat.

Namun, karena fitur ini diperkenalkan pada platform web, metode native untuk menunda permintaan gambar diperkenalkan. Elemen <img> dengan atribut loading="lazy" tidak diminta hingga tata letak halaman diketahui, untuk menunda permintaan gambar di luar area tampilan awal pengguna hingga nanti dalam proses rendering halaman, yang berpotensi menghindari permintaan yang tidak diperlukan. Karena browser sepenuhnya memahami tata letak halaman pada saat permintaan ini dibuat, atribut sizes="auto" telah diusulkan sebagai tambahan untuk spesifikasi HTML untuk menghindari tugas atribut sizes yang ditulis secara manual dalam kasus ini.

Ada juga tambahan pada elemen <picture> di cakrawala, untuk mencocokkan beberapa perubahan yang sangat menarik dengan cara kita menata gaya tata letak halaman. Meskipun informasi area pandang adalah dasar yang baik untuk keputusan tata letak tingkat tinggi, informasi tersebut mencegah kita mengambil pendekatan tingkat komponen sepenuhnya untuk pengembangan—artinya, komponen yang dapat ditempatkan ke bagian mana pun dari tata letak halaman, dengan gaya yang merespons ruang yang ditempati komponen itu sendiri. Masalah ini menyebabkan pembuatan kueri penampung: metode penataan gaya elemen berdasarkan ukuran penampung induknya, bukan area pandang saja.

Meskipun sintaksis kueri penampung baru saja stabil—dan dukungan browser sangat terbatas, pada saat penulisan—penambahan teknologi browser yang memungkinkannya akan memberikan elemen <picture> dengan cara untuk melakukan hal yang sama: atribut container potensial yang memungkinkan kriteria pemilihan <source> berdasarkan ruang yang ditempati <img> elemen <picture>, bukan berdasarkan ukuran area pandang.

Jika kedengarannya sedikit samar-samar, yah, ada alasan yang baik: diskusi standar web ini terus berlangsung, tetapi masih jauh dari selesai—Anda belum bisa menggunakannya.

Meskipun markup gambar responsif dipastikan akan semakin mudah digunakan seiring waktu, seperti teknologi web lainnya, ada sejumlah layanan, teknologi, dan framework untuk membantu meringankan beban penulisan markup ini secara manual yang tersedia. Pada modul berikutnya, kita akan melihat cara mengintegrasikan semua yang telah kita pelajari tentang format gambar, kompresi, dan gambar responsif ke dalam alur kerja pengembangan modern.