<picture>, aynı görselin farklı ekranlar ve cihazlar için alternatif sürümlerini sunmanızı sağlayan bir sarmalayıcıdır: içine sıfır veya daha fazla <source> ve en sonda bir <img> yazarsınız. Tarayıcı <source> öğelerinin media, type ve srcset özniteliklerine bakarak uygun olanı seçer; hiçbiri uymazsa <img> öğesinin src adresini kullanır. Seçilen görsel her durumda <img>'ın kapladığı alanda gösterilir.

Bu yazıda <picture> ve <source> öğelerinin HTML kurallarını MDN belgelerine göre anlatıyoruz: sanat yönetimi (art direction), biçim yedekleme, açık ve koyu tema görselleri, tanımlayıcı kuralları ve en sık yapılan hatalar. <img> öğesinin kendi öznitelikleri (alt, boyutlar, loading) img etiketi yazısında; görsel biçimi seçimi, sıkıştırma ve tembel yüklemenin optimizasyon tarafı ise görsel optimizasyonu rehberinde. Tüm seri için HTML öğrenme rehberine bakabilirsiniz.

picture hangi sorunu çözer?

MDN'nin duyarlı görseller rehberi iki ayrı sorundan söz eder. Birincisi çözünürlük değiştirme (resolution switching) sorunudur: aynı görselin küçük ekranda küçük, büyük ekranda büyük dosyasının indirilmesi istenir. Masaüstü için hazırlanmış büyük bir görseli mobil kullanıcıya indirtmek bant genişliğini boşa harcar; küçük bir görseli büyütmek ise görüntüyü bozar. Bu sorunun çoğu zaman <picture> gerektirmeyen çözümü, <img> üzerindeki srcset ve sizes öznitelikleridir.

İkincisi sanat yönetimi (art direction) sorunudur: geniş ekranda bütün sahneyi gösteren yatay bir fotoğraf, dar ekranda küçülünce ortadaki kişi seçilemez hâle gelir. Burada istenen aynı görselin küçüğü değil, farklı kırpılmış başka bir görseldir; örneğin mobilde kişiye yakınlaşan dikey bir kare. MDN bu sorunun çözümü olarak <picture> öğesini gösterir. Üçüncü yaygın kullanım da yeni görsel biçimlerini, desteklemeyen tarayıcılar için eski bir biçimle yedeklemektir.

Yapı: source öğeleri ve zorunlu img

MDN'nin teknik özetine göre <picture> içinde sırasıyla sıfır veya daha fazla <source> ve ardından tam olarak bir <img> bulunur; araya betik destekleyen öğeler girebilir. Öğenin kendine özgü bir özniteliği yoktur, yalnızca global öznitelikleri alır; örtük bir ARIA rolü yoktur ve üzerine rol verilemez. Gömülü içerik kabul eden her yerde, örneğin bir paragrafın içinde kullanılabilir.

html
<picture>
  <source srcset="manzara-genis.jpg" media="(width >= 800px)" />
  <img src="manzara-dar.jpg" alt="Göl kenarında yürüyüş yapan iki kişi" width="480" height="640" />
</picture>

<img> burada iki görev üstlenir. Birincisi, görselin boyutunu ve sunumla ilgili diğer özniteliklerini tanımlar: alt, width, height, loading gibi bilgiler <source> üzerine değil <img> üzerine yazılır. İkincisi, hiçbir <source> kullanılabilir bir görsel sağlamazsa ya da tarayıcı <picture>'ı desteklemiyorsa yedek görseli sağlar. MDN'nin duyarlı görseller rehberi bu konuda nettir: </picture> kapanışından hemen önce src ve alt taşıyan bir <img> yazmazsanız hiçbir görsel görünmez.

Aynı ilke stil için de geçerlidir. Görselin kutusunda nasıl konumlanacağını ve sığdırılacağını belirleyen CSS özellikleri <picture> üzerine değil, alttaki <img> üzerine uygulanmalıdır.

Tarayıcı hangi kaynağı seçer?

Tarayıcı hangi kaynağı seçer? media, type, srcset, Hiçbiri uymazsa

Tarayıcı <source> öğelerini yazıldıkları sırayla değerlendirir ve uygun ilk adayı kullanır. Her <source> için şu sorulara bakar:

  • media: Medya koşulu doğru mu? Yanlışsa bu <source> atlanır ve sıradakine geçilir.
  • type: Belirtilen MIME türü destekleniyor mu? Desteklenmiyorsa öğe atlanır.
  • srcset: Kalan adayın srcset listesinden, gerekirse sizes yardımıyla, ekrana en uygun dosya seçilir.
  • Hiçbiri uymazsa: <img> öğesinin src adresi kullanılır.

"İlk uyan kazanır" kuralı, <source> sırasının önemli olduğu anlamına gelir. Daha özel koşulu taşıyan kaynağı önce yazmazsanız genel koşul onu gölgeler. Bu konuya hatalar bölümünde bir örnekle döneceğiz.

Sanat yönetimi: media özniteliği

media, CSS medya sorgusuna benzeyen bir medya koşulu taşır. MDN'nin duyarlı görseller rehberindeki örnek, dar ekranlar için kişiye yakınlaşan dikey bir kırpım, geniş ekranlar için de bütün sahneyi kullanır:

html
<picture>
  <source media="(width < 800px)" srcset="aile-480w-yakin-dikey.jpg" />
  <source media="(width >= 800px)" srcset="aile-800w.jpg" />
  <img src="aile-800w.jpg" alt="Kızını kucağında tutan, ayakta duran bir baba" />
</picture>

Görüntü alanı 800 pikselden darsa birinci kaynak, en az 800 piksel ise ikinci kaynak seçilir. MDN, <img> zaten aynı geniş görseli gösterdiği için ikinci <source>'un aslında kaldırılabileceğini de not eder: hiçbir koşul tutmadığında devreye giren varsayılan durum <img>'dır.

Medya koşulları yalnızca genişlikle sınırlı değildir. MDN'nin <picture> sayfası, prefers-color-scheme medya özelliğiyle açık ve koyu tema için farklı logolar sunmayı da örnekler:

html
<picture>
  <source srcset="logo-koyu.png" media="(prefers-color-scheme: dark)" />
  <source srcset="logo-acik.png" media="(prefers-color-scheme: light)" />
  <img src="logo-acik.png" alt="Ürün logosu" width="200" height="60" />
</picture>

Yine aynı sayfadaki ilk etkileşimli örnek, (orientation: portrait) koşuluyla cihaz dikey tutulduğunda başka bir görsele geçer. Hangi koşulu kullanırsanız kullanın, mantık aynıdır: koşul doğruysa o kaynak, değilse sıradaki.

Biçim yedekleme: type özniteliği

type, srcset içindeki dosyaların MIME türünü bildirir. Tarayıcı bu türü desteklemiyorsa ilgili <source>'u dosyayı indirmeden atlar. MDN, AVIF ve WebP gibi yeni biçimlerin pek çok avantajı olduğunu ama her tarayıcıda desteklenmeyebileceğini belirtir; <picture> ile en yeniden en eskiye doğru sıralanmış bir zincir kurarsınız:

html
<picture>
  <source srcset="urun.avif" type="image/avif" />
  <source srcset="urun.webp" type="image/webp" />
  <img src="urun.jpg" alt="Ahşap tabureli mutfak tezgâhı" width="1200" height="800" />
</picture>

AVIF'i destekleyen bir tarayıcı ilk kaynakta durur, desteklemeyen ama WebP'yi anlayan bir tarayıcı ikinci kaynağa geçer, ikisini de desteklemeyen tarayıcı JPEG yedeğini kullanır. Hangi biçimin ne zaman tercih edileceği ve dosya boyutu karşılaştırmaları bu yazının değil, görsel optimizasyonu rehberinin konusu.

srcset tanımlayıcıları: w ve x

<source> içindeki srcset, <img>'daki ile aynı söz dizimini kullanır: virgülle ayrılmış adaylar, her adayın yanında ya bir genişlik tanımlayıcısı (300w) ya da bir piksel yoğunluğu tanımlayıcısı (2x). MDN üç kuralın altını çizer: iki tanımlayıcı türü birlikte kullanılmamalı, tanımlayıcısı olmayan aday 1x sayılır ve aynı değer iki kez yazılamaz (iki tane 2x ya da iki tane 100w geçersizdir).

html
<picture>
  <source srcset="logo.png, logo-1.5x.png 1.5x" />
  <img src="logo.png" alt="MDN Web Docs logosu" height="320" width="320" />
</picture>

Bu örnekte tanımlayıcısı olmayan logo.png standart yoğunluk için, logo-1.5x.png ise 1,5 kat yoğunluklu ekranlar için kullanılır. Genişlik tanımlayıcıları kullanıldığında sizes özniteliği devreye girer: medya koşulu ve uzunluk çiftleriyle görselin her durumda ne kadar genişlikte gösterileceğini anlatır. sizes yalnızca w tanımlayıcılarıyla etki eder; <source> üzerinde sizes varsa listedeki her aday bir genişlik tanımlayıcısı taşımalıdır.

html
<picture>
  <source
    srcset="kucuk.jpg 480w, orta.jpg 800w, buyuk.jpg 1200w"
    sizes="(max-width: 600px) 400px, 800px"
    type="image/jpeg" />
  <img src="yedek.jpg" alt="Örnek görsel" />
</picture>

MDN'nin açıklamasına göre görüntü alanı 600 piksel veya daha darsa görselin yuvası 400 piksel, değilse 800 pikseldir. Tarayıcı yuva genişliğini cihazın piksel oranıyla çarparak ideal görsel genişliğini bulur ve srcset içinden en yakın adayı seçer. Bu seçim, <img> sayfasının belirttiği gibi, tarayıcının takdirine bırakılmıştır; kullanıcı tercihleri ya da bağlantı koşulları da hesaba katılabilir. Tarayıcı sizes içindeki medya koşullarını herhangi bir görsel indirmeden önce değerlendirir.

Ne zaman picture, ne zaman img srcset?

Ne zaman picture, ne zaman img srcset? Aynı görsel, farklı piksel yoğunlukları, Aynı görsel, farklı yerleşim genişlikleri, Ekrana göre farklı kırpım veya kompozisyon, Yeni biçim...

MDN bu konuda açık bir yönlendirme yapar: yalnızca yüksek yoğunluklu (Retina gibi) ekranlar için daha keskin sürümler sunuyorsanız <picture> yerine <img> üzerinde srcset kullanın. Bu yaklaşım, veri tasarrufu modundaki tarayıcıların daha düşük yoğunluklu sürümü seçebilmesine olanak tanır ve sizi açık medya koşulları yazmaktan kurtarır.

İhtiyaçÖnerilen yapıNeden
Aynı görsel, farklı piksel yoğunluklarıimg + srcset (x tanımlayıcıları)Seçimi tarayıcı yapar, koşul yazmazsınız
Aynı görsel, farklı yerleşim genişlikleriimg + srcset (w) + sizesYuva genişliğine göre dosya seçilir
Ekrana göre farklı kırpım veya kompozisyonpicture + source mediaSanat yönetimi yalnızca media ile yapılır
Yeni biçim ve eski biçim yedeğipicture + source typeDesteklenmeyen tür indirilmeden atlanır
Açık ve koyu tema görselleripicture + source media (prefers-color-scheme)Tema bir medya özelliğidir

MDN'nin duyarlı görseller rehberi bir uyarı daha ekler: media özniteliğini yalnızca sanat yönetimi senaryolarında kullanın ve media kullandığınız bir kaynakta sizes içine ayrıca medya koşulları yazmayın. İki mekanizmayı aynı yerde karıştırmak hem okunmayı hem de beklenen seçimi bulanıklaştırır.

source üzerinde width ve height

Farklı kırpımların en-boy oranları farklıysa <img> üzerindeki tek bir width ve height çifti her durumu doğru tarif edemez. Bu yüzden <source> da, yalnızca üst öğesi <picture> olduğunda, birimsiz tam sayı olarak width ve height alabilir. MDN'nin örneğinde üç kaynak, görüntü alanı genişliğine göre yatay, kare ve dikey görsellere farklı boyutlar verir:

html
<picture>
  <source srcset="yatay.png" media="(width >= 1000px)" width="1000" height="400" />
  <source srcset="kare.png" media="(width >= 800px)" width="800" height="800" />
  <source srcset="dikey.png" media="(width >= 600px)" width="600" height="800" />
  <img src="yedek.png" alt="Kaynaklar desteklenmediğinde gösterilen görsel" width="500" height="400" />
</picture>

Bu örnek aynı zamanda sıralamanın nasıl kurulması gerektiğini de gösterir: en geniş koşul (1000 piksel ve üstü) en başta, en dar koşul en sonda. Görüntü alanı 1200 piksel olduğunda üç koşul da doğrudur, ama ilk uyan kazandığı için yatay görsel seçilir.

source öğesinin kuralları

source öğesinin kuralları: srcset, Kullanılamaz, sizes, width, height

<source> boş (void) bir öğedir; içeriği ve kapanış etiketi yoktur, </source> hiçbir zaman yazılmaz. Aynı öğe <video> ve <audio> içinde de kullanılır, fakat üst öğeye göre izin verilen öznitelikler değişir:

Öznitelikpicture içindevideo ve audio içinde
srcsetZorunluKullanılamaz
srcKullanılamazZorunlu
sizesKullanılabilirKullanılamaz
width, heightKullanılabilirKullanılamaz
mediaKullanılabilirKullanılabilir
typeKullanılabilirKullanılabilir

<picture> içinde <source> öğeleri <img>'dan önce gelmelidir. Video ve ses tarafındaki kullanım, type özniteliğindeki codecs parametresi ve yedek içerik davranışıyla birlikte video ve audio etiketi yazısında anlatılıyor.

Neden bunu CSS ya da JavaScript ile yapmıyoruz?

MDN bu soruyu tarayıcının yükleme sırasıyla yanıtlar. Tarayıcı bir sayfayı yüklemeye başladığında, ana ayrıştırıcı CSS ve JavaScript'i işlemeye başlamadan önce görselleri indirmeye (ön yüklemeye) başlar. Bu genel olarak sayfa yükleme süresini kısaltır, ama duyarlı görseller için bir sorun yaratır: önce <img> yüklenip ardından JavaScript ile görüntü alanı ölçülerek daha küçük bir görsele geçilirse, büyük görsel zaten indirilmiş olur ve üstüne küçük görsel de indirilir. srcset, sizes ve <picture> seçimi daha en başta, HTML içinde yaptırdığı için bu israfı önler.

Uygulama: kırpım ve biçimi birlikte sunmak

Sanat yönetimi ile biçim yedeklemeyi aynı <picture> içinde birleştirebilirsiniz. Her kırpım için önce yeni biçimi, sonra eski biçimi yazarsınız; dar ekran kaynakları da geniş ekran kaynaklarından sonra gelir:

html
<picture>
  <!-- Geniş ekran: bütün sahne -->
  <source media="(width >= 800px)" srcset="sahne-genis.avif" type="image/avif" />
  <source media="(width >= 800px)" srcset="sahne-genis.jpg" type="image/jpeg" />
  <!-- Dar ekran: kişiye yakın dikey kırpım -->
  <source srcset="sahne-dar.avif" type="image/avif" />
  <img src="sahne-dar.jpg" alt="Bisikletiyle köprüden geçen kurye" width="480" height="720" />
</picture>

Bu yapıda 900 piksel genişliğindeki ve AVIF destekleyen bir tarayıcı ilk kaynakta durur. Aynı genişlikte ama AVIF desteklemeyen bir tarayıcı, ilk kaynağı type nedeniyle atlar ve ikinci kaynaktaki JPEG'i seçer. 400 piksel genişliğindeki bir tarayıcıda ilk iki kaynağın media koşulu yanlış olduğu için seçim üçüncü kaynağa ya da <img> yedeğine düşer. MDN, bir <picture> içinde hem farklı görseller hem de her birinin farklı çözünürlüklerini sunmanın mümkün olduğunu ama gerçekte buna sık ihtiyaç duyulmayacağını da belirtir; yapıyı ihtiyacınız kadar sade tutun.

Sık yapılan hatalar

  • img yedeğini unutmak: <img> olmadan hiçbir görsel görünmez.
  • alt'ı source üzerine yazmak: Erişilebilir metin ve boyutlar <img>'a aittir.
  • Koşulları yanlış sıralamak: (width >= 600px) koşulunu (width >= 1000px) koşulundan önce yazarsanız geniş ekranlarda da ilk koşul kazanır ve en büyük görsel hiç seçilmez.
  • picture içinde src kullanmak: <picture> içindeki <source> srcset ister; src burada izinli değildir.
  • </source> yazmak: <source> boş bir öğedir.
  • w ve x tanımlayıcılarını karıştırmak: Aynı srcset içinde tek tür kullanın.
  • Yalnızca yoğunluk için picture kullanmak: MDN bu durumda <img srcset> önerir.
  • Stili picture'a vermek: Sığdırma ve konumlandırma <img> üzerinde yapılır.

Sık Sorulan Sorular

picture kullanınca img'ye yine alt yazmalı mıyım?

Evet. Hangi kaynak seçilirse seçilsin görsel <img>'ın alanında gösterilir ve erişilebilir metin <img>'ın alt özniteliğinden gelir. Görsel tamamen dekoratifse alt="" yazın.

loading="lazy" nereye yazılır?

<img> üzerine. <picture>'ın kendi özniteliği yoktur; görselin sunumuyla ilgili tüm öznitelikler <img>'da tanımlanır.

Hiçbir source eşleşmezse ne olur?

Tarayıcı <img> öğesinin src adresini kullanır. <picture>'ı desteklemeyen tarayıcılar da yalnızca <img>'ı görür ve onu gösterir.

type yazmazsam ne olur?

type isteğe bağlıdır. Yazdığınızda tarayıcı desteklemediği türdeki kaynağı indirmeden atlayabilir; biçim yedeklemesi yapıyorsanız bu yüzden her <source> için türü belirtin.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: HTML öğrenme rehberi · img etiketi · Görsel optimizasyonu · video ve audio etiketi · Mobil uyumluluk · preload ve fetchpriority