Albumler sayfasında (ve muhtemelen diğer sayfalarda) mobilde aşağı kaydırma sorunu analizi
📱 Kullanıcı Şikayeti: "Aşağı kaydırmak istediğimde herzaman değil ama bazen kaydırmıyor. Aşağı kaymıyor, bunun için sayfa yenilemem gerekiyor. Yeniledikten sonra aşağı kayıyor. 10 kerede 4 kere falan yaşadım bunu."
🎯 Davranış: Albumler sayfasında (ve muhtemelen diğer sayfalarda da) mobilde aşağı kaydırırken sayfa yukarı kısmını tekrar gösteriyor. Alt içerik görünmüyor.
🔄 Tekrarlama: Sık değil ama düzenli (10 denemede 4 kere). Sayfa yenilenince geçici olarak düzeliyor.
Telefonda müzik sitesinde gezinirken bazen ekranı aşağı kaydıramıyorsunuz. Parmağınızı aşağı kaydırıyorsunuz ama sayfa yukarı kısmını tekrar gösteriyor, aşağıdaki içerik görünmüyor. Bu sorun her seferinde olmuyor, 10 denemede 4-5 kere yaşanıyor.
Ana sebep: Sayfanın scroll (kaydırma) sistemi çok karmaşık ve birbiriyle çakışan birçok katman var. Şöyle düşünün:
Sayfaya ilk girdiğinizde veya yenilediğinizde kodlar doğru çalışıyor. Ama bazı durumlar scroll'u bozuyor:
Scroll sistemini basitleştireceğiz ve katmanları azaltacağız:
overflow-hidden kaldırılacakposition: fixed kaldırılacak-webkit-overflow-scrolling: touch eklenecekstopPropagation ile izole edilecekSistem şu anda çok katmanlı bir scroll yapısı kullanıyor ve bu katmanlar bazen birbirini engelliyor. Basitleştirip tek bir scroll sistemiyle çalıştıracağız. Sayfa yenilendiğinde düzelmesinin sebebi de bu - yeni baştan yüklenince kodlar temiz çalışıyor, sonra tekrar karışıyor.
Dosya: resources/views/themes/muzibu/layouts/app.blade.php:786
<body class="bg-black text-white overflow-hidden">
Etki: Body scroll baştan kapalı. Tüm scroll main content içindeki div'e bağımlı.
Risk: CSS class inline style ile override edilse bile class kalıyor, conflict oluşturuyor.
Dosya: public/themes/muzibu/css/muzibu-layout.css:1301-1307
@media (max-width: 1023px) {
#main-app-grid {
position: fixed;
left: 0;
right: 0;
}
}
Etki: Mobilde grid fixed pozisyonda, scroll framework'ü bozuyor.
Risk: Fixed element içinde scroll sorunlu, iOS'ta daha da kötü.
Dosya: resources/views/themes/muzibu/layouts/app.blade.php:1160-1179
function toggleMobileMenu() {
const isOpen = sidebar.classList.contains('active');
if (isOpen) {
// Close
document.body.style.overflow = ''; // ⚠️ Sadece inline style kaldırır
} else {
// Open
document.body.style.overflow = 'hidden'; // ❌ Body kilitleniyor
}
}
Etki: Mobile menu açılınca body kilitleniyor. Kapanınca inline style kaldırılıyor AMA CSS class overflow-hidden kalıyor!
Risk: Menu açılıp kapandıktan sonra scroll bozuluyor çünkü hem CSS class hem inline style kontrolü var.
Dosya: resources/views/themes/muzibu/layouts/app.blade.php:886-909
<main class="muzibu-main row-start-2 relative overflow-hidden"> <div class="overflow-y-auto h-full relative"> <!-- Gradient Background --> <div class="absolute top-0 ... h-[250px]"></div> <!-- Content (Gradient ile birlikte scroll yapar) --> <div class="relative z-10"> @yield('content') </div> </div> </main>
Etki: İç içe 3 katman: Body → Main → Scroll Div → Content. Touch event'leri hangi katmanda yakalanacak belirsiz.
Risk: iOS Safari nested scroll container'larda momentum scroll'u kaybediyor.
Dosya: resources/views/themes/muzibu/layouts/app.blade.php:874
<div id="main-app-grid"
class="grid ... h-[100dvh]">
Etki: Safari'de dvh (Dynamic Viewport Height) adres çubuğu gösterilip gizlenince yeniden hesaplanıyor. Bu sırada scroll position kayboluyor.
Risk: Kullanıcı aşağı kaydırınca adres çubuğu gizleniyor → dvh değişiyor → scroll position resetleniyor → sayfa yukarı zıplıyor!
Dosya: resources/views/themes/muzibu/components/player.blade.php:152-162
<div class="... touch-none" @touchstart.prevent="..." @touchmove.prevent="..." @touchend.prevent="...">
Etki: Player progress bar'da touchmove.prevent var. Bu tüm touch event'lerini engelliyor, scroll da etkileniyor.
Risk: Kullanıcı progress bar yakınında scroll yapmaya çalışırsa touch event preventDefault yüzünden scroll çalışmıyor.
Dosya: public/themes/muzibu/css/muzibu-layout.css
/* ❌ EKSİK: iOS için momentum scroll */
.muzibu-main > div {
overflow-y: auto;
/* -webkit-overflow-scrolling: touch; EKSIK! */
}
Etki: iOS'ta smooth momentum scroll çalışmıyor, scroll hissiyat kötü.
Risk: Kullanıcı scroll yaparken "yapışkan" hissiyat alıyor, doğal scroll davranışı yok.
Dosya: resources/views/themes/muzibu/playlists/my-playlists.blade.php:91
watch(showPlaylistModal, (value) => {
document.body.style.overflow = value ? 'hidden' : '';
});
Etki: Modal açılınca body kilitleniyor, kapanınca inline style kaldırılıyor AMA CSS class overflow-hidden kalıyor.
Risk: Modal açılıp kapandıktan sonra scroll çalışmıyor çünkü body overflow kontrolü karışık.
Dosya: app.blade.php:786
- <body class="bg-black text-white overflow-hidden"> + <body class="bg-black text-white">
Body scroll'u açık bırak, overflow kontrolünü CSS'e bırakma.
Dosya: muzibu-layout.css:1301-1307
- @media (max-width: 1023px) { - #main-app-grid { - position: fixed; - left: 0; - right: 0; - } - }
Grid'i normal flow'da bırak, fixed pozisyon gereksiz.
Dosya: app.blade.php:886-909
- <main class="muzibu-main row-start-2 relative overflow-hidden"> - <div class="overflow-y-auto h-full relative"> + <main class="muzibu-main row-start-2 relative overflow-y-auto"> <!-- Gradient --> <div class="relative z-10"> @yield('content') </div> - </div> </main>
Nested scroll container kaldır, main doğrudan scroll yapsın.
Dosya: muzibu-layout.css (veya tenant-1001.css)
+ .muzibu-main { + overflow-y: auto; + -webkit-overflow-scrolling: touch; /* iOS smooth scroll */ + }
iOS'ta smooth momentum scroll için gerekli.
Dosya: app.blade.php:874
- class="grid ... h-[100dvh]" + class="grid ... h-screen" {{-- 100vh daha stabil --}}
dvh Safari'de sorunlu, vh daha güvenilir. Ya da CSS'te calc(100vh - env(safe-area-inset-bottom)) kullan.
Dosya: app.blade.php:1160-1179
function toggleMobileMenu() {
const isOpen = sidebar.classList.contains('active');
if (isOpen) {
sidebar.classList.remove('active');
overlay.classList.remove('active');
- document.body.style.overflow = '';
+ document.body.classList.remove('overflow-hidden');
} else {
sidebar.classList.add('active');
overlay.classList.add('active');
- document.body.style.overflow = 'hidden';
+ document.body.classList.add('overflow-hidden');
}
}
CSS class kontrolü kullan, inline style değil. Daha güvenilir.
Dosya: player.blade.php:152-162
<div class="... touch-none" - @touchmove.prevent="..." + @touchmove.stop.prevent="..." @touchend.prevent="...">
stop modifier ekleyerek event propagation'ı engelle, sadece progress bar etkilensin.
Dosya: my-playlists.blade.php:91
watch(showPlaylistModal, (value) => {
- document.body.style.overflow = value ? 'hidden' : '';
+ if (value) {
+ document.body.classList.add('overflow-hidden');
+ } else {
+ document.body.classList.remove('overflow-hidden');
+ }
});
CSS class kontrolü kullan, tüm modal'larda tutarlı olsun.
Dosya: global-helpers.js (veya yeni dosya)
+ // 🔒 Body Scroll Lock Helper (Tüm modal/overlay'ler için) + window.bodyScrollLock = { + lock() { + document.body.classList.add('overflow-hidden'); + }, + unlock() { + document.body.classList.remove('overflow-hidden'); + } + };
Tüm modal/overlay/menu'lerde aynı helper kullan, tutarlılık sağla.
Değişikliklerden sonra test adımları:
# 1. Cache temizle php artisan cache:clear php artisan view:clear php artisan responsecache:clear # 2. CSS rebuild npm run prod # 3. Test senaryoları: # - Albumler sayfasında scroll (mobil) # - Mobile menu aç/kapat, sonra scroll # - Player progress bar'a dokun, sonra scroll # - Playlist modal aç/kapat, sonra scroll # - Safari'de scroll (iOS simülatör) # - Chrome DevTools mobile mode
Body overflow-hidden kaldırınca desktop'ta layout bozulabilir.
Önlem: Desktop'ta body'ye overflow-y: auto ekle, mobilde overflow: visible yap.
Grid fixed position kaldırınca tablet/desktop'ta header/player konumları kayabilir.
Önlem: Tablet+ (768px) için sticky position kullan: header sticky top-0, player sticky bottom-0.
Nested scroll container kaldırınca gradient background position'ı değişebilir.
Önlem: Gradient'i position: fixed yap veya CSS ile main'e background ekle.
Body lock helper tutarlı çalışmazsa modal'lar scroll'u kilitlemiş bırakabilir.
Önlem: Helper'da counter mechanism kullan (birden fazla modal açıksa unlock yapma).
Mobil scroll sistemi çok katmanlı ve karmaşık. Body overflow kapalı, grid fixed, nested scroll container, iOS dvh sorunu, touch event conflict ve modal body lock'ları birleşince kullanıcı deneyimi bozuluyor.
Over-engineering: Scroll için çok fazla katman ve kontrol mekanizması var. Basit scroll sistemini kompleks hale getirmişiz.
Simplification (Basitleştirme): Scroll sistemini tek katmana indirgeyeceğiz. Body scroll açık, main content overflow-y: auto, iOS momentum scroll aktif, modal/menu'ler için tutarlı body lock helper.
Implementation: 2-3 saat
Testing: 1-2 saat
Toplam: 3-5 saat (tek bir oturumda bitirilebilir)
🤖 Bu rapor Claude AI (Sonnet 4.5) tarafından oluşturuldu