Merhaba arkadaşlar, bugün başımı çok ağrıtan bir sorunu ve onun en temiz çözümünü anlatacağım. Hepimiz CSS'te vh (viewport height) ve vw (viewport width) unit'lerini seviyoruz, değil mi? Tam ekran bir bölüm yapmak için height: 100vh yazdığımızda, masaüstünde her şey harika görünüyor. Ama iş mobile browser'lara (özellikle Safari ve Chrome mobile) gelince, durum değişiyor.
Karşılaştığım Sorun
Projede tam ekran bir hero section yapmıştım. Masaüstünde test ederken sorun yoktu. Ama siteyi telefonda açtığımda, alt kısımda bir kaydırma çubuğu oluştu ve içerik kesiliyor gibiydi. İlk başta responsive kodlarımda bir hata var sandım, saatlerce debug ettim. Sonra fark ettim ki, mobil tarayıcıların (Safari iOS, Chrome Android) dinamik UI çubukları (adres çubuğu, alt navigasyon barı) viewport boyutunu sürekli değiştiriyor. 100vh değeri, bu çubuklar görünürken mi yoksa gizliyken mi hesaplanıyor, belli değil! Bu yüzden 100vh, gerçek görüntü alanından (visual viewport) daha büyük olabiliyor ve içerik kesiliyordu. Bu hatayı ilk gördüğümde kafayı yemiştim.
JavaScript ile Dinamik Çözüm
İlk aklıma gelen, viewport yüksekliğini JavaScript ile alıp, bir CSS değişkeni (--vh) olarak atamak oldu. Bu sayede tarayıcının o anki innerHeight değerini kullanabilecektim.
İşte benim kullandığım en temiz çözüm:
Bu script, tarayıcı penceresinin gerçek yüksekliğini (pixel cinsinden) alıp, bunun yüzde birini hesaplıyor. Daha sonra bunu kök elemente (:root) bir CSS değişkeni olarak (--vh) atıyor. orientationchange event'ini de eklemek çok önemli, cihazın yönü değiştiğinde de değeri güncelliyor.
CSS Tarafında Kullanım
Artık CSS tarafında, 100vh yerine, hesapladığımız bu dinamik değeri kullanabiliriz.
calc(var(--vh, 1vh) 100) yazarak, JavaScript'in atadığı --vh değişkenini kullanıyoruz. Parantez içindeki 1vh ise bir fallback (yedek) değer. Eğer bir nedenden dolayı --vh değişkeni tanımlanmamışsa (JS yüklenmezse), tarayıcı standart 1vh değerini kullanacak ve tasarım tamamen çökmeyecek.
Sonuç ve Öneriler
Bu yöntemi uyguladıktan sonra, mobildeki tüm viewport boyutu tutarsızlıkları ve gereksiz kaydırma çubukları ortadan kalktı. Artık hero bölümüm tam olarak ekranı kaplıyor, UI çubukları görünür veya gizli olsun fark etmiyor.
Bu sorun özellikle Safari'de çok yaygın. Siz de 100vh kullanırken benzer sorunlarla karşılaştınız mı? Ya da mobil viewport sorunları için farklı, daha havalı bir çözümünüz var mı? Yorumlarda paylaşın, hep birlikte öğrenelim!
Projede tam ekran bir hero section yapmıştım. Masaüstünde test ederken sorun yoktu. Ama siteyi telefonda açtığımda, alt kısımda bir kaydırma çubuğu oluştu ve içerik kesiliyor gibiydi. İlk başta responsive kodlarımda bir hata var sandım, saatlerce debug ettim. Sonra fark ettim ki, mobil tarayıcıların (Safari iOS, Chrome Android) dinamik UI çubukları (adres çubuğu, alt navigasyon barı) viewport boyutunu sürekli değiştiriyor. 100vh değeri, bu çubuklar görünürken mi yoksa gizliyken mi hesaplanıyor, belli değil! Bu yüzden 100vh, gerçek görüntü alanından (visual viewport) daha büyük olabiliyor ve içerik kesiliyordu. Bu hatayı ilk gördüğümde kafayı yemiştim.
İlk aklıma gelen, viewport yüksekliğini JavaScript ile alıp, bir CSS değişkeni (--vh) olarak atamak oldu. Bu sayede tarayıcının o anki innerHeight değerini kullanabilecektim.
İşte benim kullandığım en temiz çözüm:
JavaScript:
// Viewport yüksekliğini hesapla ve CSS değişkeni olarak ata
function setVhUnit() {
let vh = window.innerHeight 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
}
// Sayfa yüklendiğinde ve boyut değiştiğinde çalıştır
setVhUnit();
window.addEventListener('resize', setVhUnit);
window.addEventListener('orientationchange', setVhUnit);
Bu script, tarayıcı penceresinin gerçek yüksekliğini (pixel cinsinden) alıp, bunun yüzde birini hesaplıyor. Daha sonra bunu kök elemente (:root) bir CSS değişkeni olarak (--vh) atıyor. orientationchange event'ini de eklemek çok önemli, cihazın yönü değiştiğinde de değeri güncelliyor.
Artık CSS tarafında, 100vh yerine, hesapladığımız bu dinamik değeri kullanabiliriz.
CSS:
.hero-section {
/ Eski, sorunlu yöntem /
/ height: 100vh; /
/ Yeni, güvenilir yöntem /
height: calc(var(--vh, 1vh) 100);
}
.fullscreen-element {
min-height: calc(var(--vh, 1vh) 100);
}
calc(var(--vh, 1vh) 100) yazarak, JavaScript'in atadığı --vh değişkenini kullanıyoruz. Parantez içindeki 1vh ise bir fallback (yedek) değer. Eğer bir nedenden dolayı --vh değişkeni tanımlanmamışsa (JS yüklenmezse), tarayıcı standart 1vh değerini kullanacak ve tasarım tamamen çökmeyecek.
Bu yöntemi uyguladıktan sonra, mobildeki tüm viewport boyutu tutarsızlıkları ve gereksiz kaydırma çubukları ortadan kalktı. Artık hero bölümüm tam olarak ekranı kaplıyor, UI çubukları görünür veya gizli olsun fark etmiyor.
Bu sorun özellikle Safari'de çok yaygın. Siz de 100vh kullanırken benzer sorunlarla karşılaştınız mı? Ya da mobil viewport sorunları için farklı, daha havalı bir çözümünüz var mı? Yorumlarda paylaşın, hep birlikte öğrenelim!