9 Kasım 2026 · Web geliştirme
Chrome 157 ile HTML-in-Canvas kararlı sürümde: Canvas içindeki arayüz artık gerçek DOM olabilir
Chrome 157 ile gelen HTML-in-Canvas API'si, gerçek HTML elemanlarını canvas'a çizmeyi ve bu içeriğin erişilebilir, seçilebilir ve çevrilebilir kalmasını sağlıyor. Firefox ise henüz ikna olmuş değil. Bu yazıda API'nin neyi çözdüğüne ve bugün nasıl kullanılabileceğine bakıyoruz.
Canvas ile çalışmış herkesin bildiği bir sorun var: Canvas'a çizdiğiniz her şey tarayıcı açısından anlamsız piksellerden ibaret. Ekran okuyucular o metni okuyamaz, Ctrl+F onu bulamaz, otomatik çeviri dokunamaz, kullanıcı seçip kopyalayamaz. Bu yüzden oyunlarda, veri görselleştirmelerinde ya da 3B sahnelerde arayüzü genellikle canvas'ın üstüne mutlak konumlu HTML katmanları koyarak çözüyoruz. Ya da metin düzenini, satır kırmayı, input'ları canvas içinde baştan yazıyoruz.
3 Kasım'da kararlı kanala çıkan Chrome 157 bu konuda önemli bir adım atıyor: HTML-in-Canvas API'si artık bayrak arkasında değil. Gerçek DOM elemanlarını 2D, WebGL ve WebGPU canvas'larına çizebiliyorsunuz ve bu elemanlar DOM'da kalmaya devam ettiği için erişilebilirlik, bul-getir, çeviri ve DevTools gibi özellikler çalışmayı sürdürüyor.
API nasıl çalışıyor?
Model aslında basit. Canvas'ın içine koyduğunuz alt elemanlar artık yalnızca "fallback" içerik değil. Canvas'a content="drawable" verdiğinizde tarayıcı bu alt ağacı yerleşimden (layout) geçiriyor. Çizmek istediğiniz her elemanı da drawable özniteliğiyle işaretliyorsunuz. Sonra çizimi paint olayında yapıyorsunuz:
<canvas id="c" content="drawable" style="width:400px;height:200px">
<form id="panel" drawable>
<label>E-posta <input type="email"></label>
<button type="submit">Gönder</button>
</form>
</canvas>
<script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
const panel = document.getElementById('panel');
canvas.onpaint = () => {
ctx.reset();
ctx.drawElementImage(panel, 0, 0);
};
</script>Buradaki form gerçek bir form: input'a yazabiliyor, butona tıklayabiliyorsunuz. 2D bağlamda drawElementImage() elemanı nereye çizdiyseniz, tıklama alanını (hit-test) ve ekran okuyucunun odak çerçevesini de oraya otomatik olarak hizalıyor.
3B tarafında işler biraz daha elle yürüyor:
- WebGL:
texElementSubImage2D()ile elemanı önceden ayrılmış bir dokuya kopyalıyorsunuz. - WebGPU:
device.queue.drawElementImageToTexture()aynı işi görüyor. - Bu iki durumda tarayıcı, elemanı sahnede nereye yerleştirdiğinizi bilemiyor. O yüzden tıklama ve erişilebilirlik için
canvas.updateElementGeometry()ile bir dönüşüm matrisi vermeniz gerekiyor. Vermezseniz eleman erişilebilirlik ağacında kalıyor ama ekranda bir konumu olmuyor.
Performans için de bir ipucu var: paint olayındaki changedElements listesi, görünümü değişen elemanları söylüyor. Böylece her karede her şeyi yeniden çizmek yerine yalnızca değişeni güncelleyebiliyorsunuz.
Neden önemli?
Bence buradaki asıl kazanç, iki dünya arasındaki duvarın incelmesi. Bugüne kadar "canvas'ta güzel efekt" ile "erişilebilir, çevrilebilir arayüz" arasında seçim yapmak zorunda kalıyorduk. Pratikte bu şu anlama geliyor:
- Oyun ve 3B arayüzleri: Menü, envanter ya da sohbet paneli gibi parçaları HTML ve CSS ile yazıp dokuya çevirebilirsiniz. Metin düzeni, RTL diller, emoji ve yazı tipi fallback'i için kendi motorunuzu yazmanız gerekmez.
- Veri görselleştirme: Grafik etiketleri ve açıklamalar gerçek metin olarak kalır, ekran okuyucu ve sayfa içi arama onları görür.
- Editörler ve tasarım araçları: Canvas tabanlı editörlerde metin alanlarını yeniden icat etme ihtiyacı azalır.
- Ekran görüntüsü ve dışa aktarma: html2canvas gibi DOM'u JavaScript ile yeniden çizmeye çalışan kütüphanelerin yerine tarayıcının kendi render çıktısını kullanma imkânı doğuyor.
Ayrıca API olgunlaşırken birkaç kez değişti. Chrome 150 ve 155'te metot imzaları ve isimleri değişti, eski boolean layoutsubtree özniteliği content="drawable" oldu. Origin trial döneminde yazdığınız kod varsa önce bu isim değişikliklerini kontrol etmenizde fayda var.
Madalyonun öbür yüzü: Firefox ikna olmuş değil
Bu özelliği hemen her projeye taşımadan önce standart tarafındaki tabloya bakmak gerekiyor. Şu an yalnızca Chromium tabanlı tarayıcılarda var. Safari ve Firefox'ta bir uygulama yok.
Mozilla'nın standards-positions deposundaki tartışma oldukça öğretici. Mozilla henüz resmi bir pozisyon açıklamış değil, ama dile getirilen endişeler ciddi:
- Gizlilik ve parmak izi (fingerprinting): Script'lerin render edilmiş DOM piksellerini okuyabilmesi, form kontrolleri veya kaydırma çubukları gibi tarayıcıya özgü görünümleri sızdırabilir. Chrome tarafı bunun için cross-origin içeriği dışlayan bir "okuma modu" tasarladığını söylüyor. Mozilla ise bu tür bir dışlama listesinin hiç bitmeyeceğini savunuyor.
- Platformun yönü: Mozilla, zengin arayüzleri canvas üzerine kurmayı teşvik etmenin web için doğru yön olmadığını, render hattındaki önemli optimizasyonları da zayıflatabileceğini düşünüyor.
- Uyumluluk baskısı: Tek bir motorda yaygınlaşan bir API, diğer tarayıcılar üzerinde fiili standart baskısı yaratabilir.
Chrome'un kendi rehberi de net bir sınır koyuyor: Canvas içine cross-origin içerik gömmek desteklenmiyor. Yani iframe'li reklam ya da üçüncü parti widget'ları canvas'a çizmeyi beklemeyin.
Pratikte ne yapmalı?
Bugün production'da kullanmak istiyorsanız tek doğru yol progressive enhancement:
if ('content' in HTMLCanvasElement.prototype) {
// HTML-in-Canvas yolu
} else {
// HTML'i canvas'ın üstüne CSS ile konumlandır
}Birkaç öneri:
- Fallback'i birincil yol gibi tasarlayın. Safari ve Firefox kullanıcıları sizin için "kenar durum" değil. Klasik "canvas üstünde HTML katmanı" çözümü çalışır kalsın.
- Erişilebilirliği otomatik saymayın. 2D'de çoğu şey kendiliğinden hizalanıyor, ama WebGL/WebGPU'da
updateElementGeometry()çağrısını unutursanız ekran okuyucu kullanıcıları için bozuk bir deneyim çıkar. - Önce iç araçlarda deneyin. Kontrol ettiğiniz bir tarayıcı ortamı olan dashboard'lar, Electron uygulamaları veya kiosk ekranları iyi bir başlangıç noktası.
- Standart sürecini takip edin. API WHATWG'ye taşınma yolunda, ayrıntılar hâlâ değişebilir.
Son söz
HTML-in-Canvas, web platformunun uzun süredir yaşadığı bir ikilemi çözmeye aday: Görsel özgürlük ile erişilebilirliği aynı anda sunmak. Chrome 157 ile bunu artık bayraksız deneyebiliyoruz. Ancak bir API'nin tek tarayıcıda kararlı olması, web'in kararlı bir parçası olduğu anlamına gelmiyor. Benim önerim; yeni oyun arayüzünüzü, grafik kütüphanenizi ya da canvas tabanlı editörünüzü bu API'yi destekleyecek şekilde tasarlayın, ama bu API olmadan da çalışabilsin. Firefox ve Safari'nin vereceği karar, bu özelliğin bir "Chrome özelliği" olarak mı kalacağını yoksa web'in ortak aracı mı olacağını belirleyecek.
Kaynaklar
- Expose canvas content to browser features – Chrome for Developers
- HTML-in-Canvas updates: Iterating toward a better Web API – Chrome for Developers
- Chrome 157 HTML-in-Canvas API – mdn/browser-compat-data PR #30938
- Chrome 157 Is Out: 213 Security Fixes and What Is New – Chrome Geek
- Mozilla standards-positions: HTML-in-canvas (issue #1076)
- WICG html-in-canvas explainer
- This Week In React #304