İçeriğe atla
İlyas Saltay

Yazılar · PDF · CSS · iOS

PDF'teki gölgeler iPhone'da siyah kutu çıkıyor: Chrome print-to-PDF ve SMask

2 dakika okumaİlyas Saltay

Kısa cevap

Chrome'un print-to-PDF motoru blur'lu ya da alfalı her box-shadow'u PDF'e bir SMask saydamlık grubu olarak gömer. Chrome ve Acrobat bunu doğru çözer, iOS PDFKit (Safari, Dosyalar, Quick Look) çözemez ve gölgenin taban rengini tam opak basar: her kartın arkasında siyah kutu. Kural: HTML'den PDF'e basılan belgelerde kart ayrımı gölgeyle değil opak yüzey rengi ve köşe yuvarlatmasıyla yapılır. Teslimden önce PDF'teki gölge maskesi sayısı sıfır olmalı.

Özgeçmişimi sitemden PDF olarak indirilebilir tutuyorum. Bir gün telefonumdan açtım ve her kartın arkasında simsiyah bir kutu vardı. Masaüstünde aynı dosya kusursuzdu; CSS'teki gölge ne kadar yumuşaksa PDF'te de o kadar yumuşak görünüyordu. Ölçtüm, karşılaştırdım, fark yoktu. Sorun ancak hangi cihazda bozulduğunu sorunca ortaya çıktı. Bu yazı o tuzağı, teşhisini ve bir daha yaşanmaması için kurduğum mekanik kontrolü anlatıyor.

Mekanizma

Chrome --print-to-pdf ile bir sayfayı basarken blur'lu ya da saydam her box-shadow'u PDF'in içine bir SMask, yani yumuşak maskeli saydamlık grubu olarak gömer. Bu PDF standardında geçerli bir yapı; Chrome'un kendi görüntüleyicisi ve Acrobat doğru çözer. Bu yüzden masaüstünde test edince "sorun yok" görürsün. iOS'un PDFKit motoru, yani iPhone'daki Safari, Dosyalar ve Quick Look, bu maskeyi çözemiyor ve gölgenin taban rengini tam opaklıkta basıyor. Yumuşak gri bir gölge, keskin siyah bir dikdörtgene dönüyor.

İki farklı SMask var, karıştırma

İlk yazdığım denetleyici PDF'teki bütün /SMask geçişlerini saydı ve yedi tane sorunsuz teklif belgesini boş yere "riskli" işaretledi. Ayrım şart; yanlış alarm veren bir kapıyı kimse ciddiye almaz.

NePDF'teki iziDurum
Gölge maskesi/Type /ExtGState /SMask <</Type /Mask /S /Luminosity …>>iOS'u zorlayan bu
Görüntü alfası/Subtype /Image … /SMask 12 0 R (saydam PNG logo gibi)Her motor doğru basar

Kalibrasyon için kendi belgelerimde saydım: eski özgeçmiş 36 gölge maskesi taşıyordu, düzeltilmiş sürüm sıfır. Antetli teklif ve proforma belgelerinde gölge yoktu, yalnız saydam PNG logo vardı; sorun yalnız özgeçmişe özeldi.

Teşhis, bir saniyede

PDF metin tabanlı bir biçim; maskeleri saymak için harici araç gerekmez. Ham dosyada gölge maskesi imzasını aramak yeter:

node -e '
const s = require("fs").readFileSync(process.argv[1], "latin1");
const golge = (s.match(/\/SMask\s*<<[^>]*\/S\s*\/Luminosity/g) || []).length;
console.log("gölge maskesi:", golge, golge ? "→ iOS riski" : "→ temiz");
' belge.pdf

Bunu özgeçmişimin PDF üretim adımına zorunlu kapı olarak bağladım: sayı sıfır değilse script hata verir, dosya "hazır" demez. Kuralı nota bırakmak yetmiyor; insan unutur, script unutmaz.

Kalıcı kural

Ekranda box-shadow serbest; kural yalnız PDF'e basılan belgeler için. Orada kart ayrımı opak bir yüzey rengi ve köşe yuvarlatmasıyla yapılır: beyaz sayfa üstünde açık gri dolgulu kart, kenarlık da yok. Alfalı halkalar ve alfalı dolgular da aynı sınıfa girer; opak karşılığı hesaplanıp yazılır. Yan fayda beklemediğim kadar büyüktü: gölgeler kalkınca özgeçmişin PDF'i 1445 KB'tan 1140 KB'a düştü, çünkü her gölge ayrı bir maske görüntüsü olarak gömülüyormuş.

Aynı aileden bir tuzak daha: tam sayfa CSS degradesi PDF'te kutu kutu bantlanır. Degradeyi dither uygulanmış bir bitmap olarak pişirip arka plana koymak, yumuşak geçişi her görüntüleyicide korur.

Bu yazı neye dayanıyor

17 Ağustos 2026, kendi özgeçmişim. Masaüstü ölçümü CSS ile birebirdi, iPhone'da siyah kutular vardı; teşhis "hangi cihaz?" sorusuyla geldi. O günden beri HTML'den PDF üreten her işte, teslimden önce gölge maskesi sayısına bakıyorum ve "bende düzgün görünüyor" cümlesini kanıt saymıyorum.

İlyas Saltay
İlyas Saltay

Yazılım ve sistem mimarı, AlgowAI'da COO. Bu yazıdaki her şey canlı bir sistemde ölçülerek yaşandı; tahmin yok. Sorun sende de varsa yaz, bakarım.

Aynı sorun sende de mi var?

Sunucu, önbellek, arama görünürlüğü ya da yayın sonrası bir arıza; yazın, aynı gün dönerim.

contact@ilyassaltay.com