🐛 Kritik Bug 📱 Mobil 🎨 Frontend

Mobil Scroll Sorunu: Detaylı Analiz

Albumler sayfasında (ve muhtemelen diğer sayfalarda) mobilde aşağı kaydırma sorunu analizi

📅 12 Ocak 2026 ⏱️ Analiz Süresi: 45 dakika 🎯 Öncelik: Çok Yüksek

Sorun Açıklaması

📱 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.

📝 Basit Anlatım (Herkes İçin)

Ne Oluyor?

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.

Neden Oluyor?

Ana sebep: Sayfanın scroll (kaydırma) sistemi çok karmaşık ve birbiriyle çakışan birçok katman var. Şöyle düşünün:

  • Body (Ana gövde) scroll kapalı
  • Grid (Izgara düzeni) fixed (sabit) konumda
  • Main (İçerik alanı) içinde bir div scroll yapıyor
  • Mobile menu açılınca body'yi kilitleyen kod var
  • Player bar touch (dokunma) eventlerini yakalıyor
  • iOS Safari'de 100dvh (dinamik yükseklik) hesaplaması bazen yanlış

Neden Bazen Çalışıyor?

Sayfaya ilk girdiğinizde veya yenilediğinizde kodlar doğru çalışıyor. Ama bazı durumlar scroll'u bozuyor:

  • Mobile menu açıp kapatınca → Body scroll kilidi kalabiliyor
  • Player progress bar'a dokunduğunuzda → Touch event'leri çakışıyor
  • Safari adres çubuğu gösterilip gizlenince → Yükseklik hesaplaması bozuluyor
  • Playlist modal açılıp kapanınca → Body overflow kontrolü karışıyor

Çözüm Nasıl Olacak?

Scroll sistemini basitleştireceğiz ve katmanları azaltacağız:

  1. Body'den overflow-hidden kaldırılacak
  2. Grid'den position: fixed kaldırılacak
  3. Main content doğrudan scroll yapacak (nested scroll olmayacak)
  4. iOS için -webkit-overflow-scrolling: touch eklenecek
  5. Mobile menu ve modal'ların body kilitleme sistemi düzeltilecek
  6. Player progress bar touch event'leri stopPropagation ile izole edilecek

💡 Özetle

Sistem ş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.

🔧 Teknik Detaylar (Geliştiriciler İçin)

❌ Sorun #1: Body overflow-hidden (CSS Class)

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.

❌ Sorun #2: Grid Fixed Position (Mobil)

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ü.

❌ Sorun #3: Mobile Menu Body Lock Conflict

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.

❌ Sorun #4: Nested Scroll Containers

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.

❌ Sorun #5: 100dvh iOS Sorunu

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!

❌ Sorun #6: Player Progress Bar Touch Conflict

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.

❌ Sorun #7: iOS Momentum Scroll Eksik

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.

❌ Sorun #8: Playlist Modal Body Lock

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.

✅ Çözüm Planı (Step-by-Step)

1

Body overflow-hidden Kaldır

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.

2

Grid Fixed Position Kaldır

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.

3

Main Content Scroll Basitleştir

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.

4

iOS Momentum Scroll Ekle

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.

5

100dvh → 100vh (iOS Fix)

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.

6

Mobile Menu Body Lock Düzelt

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.

7

Player Progress Touch Event İzole Et

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.

8

Playlist Modal Body Lock Düzelt

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.

9

Global Body Lock Helper Oluştur

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.

10

Test & Cache Temizliği

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

🧪 Test Senaryoları

1️⃣ Temel Scroll Test (En Önemli)

  • ✓ Albumler sayfasına git
  • ✓ Sayfayı yenile
  • ✓ 10 kere yukarı aşağı scroll yap
  • ✓ Her seferinde alt içeriği görmeli
  • ✓ Sayfa yukarı zıplamamalı

2️⃣ Mobile Menu Test

  • ✓ Mobile menu aç
  • ✓ Overlay'e tıklayarak kapat
  • ✓ Scroll yap (çalışmalı)
  • ✓ Tekrar menu aç/kapat
  • ✓ Scroll hala çalışmalı

3️⃣ Player Bar Test

  • ✓ Şarkı çal
  • ✓ Progress bar'a dokun ve kaydır
  • ✓ Sonra sayfa scroll'u yap
  • ✓ Scroll çalışmalı (progress bar event'i izole olmalı)

4️⃣ iOS Safari Test (Kritik)

  • ✓ iOS cihaz veya simülatör
  • ✓ Safari'de aç
  • ✓ Scroll yap, adres çubuğu gizlensin
  • ✓ Devam et scroll yapmaya
  • ✓ Sayfa yukarı zıplamamalı
  • ✓ Momentum scroll smooth olmalı

5️⃣ Playlist Modal Test

  • ✓ Playlist modal aç
  • ✓ Modal'ı kapat
  • ✓ Scroll yap (çalışmalı)
  • ✓ Body overflow kilidi kalmamalı

6️⃣ Stres Test (10 Tekrar)

  • ✓ Tüm senaryoları 10 kere tekrarla
  • ✓ Her seferinde scroll çalışmalı
  • ✓ "10 kerede 4 kere" sorunu kalmamalı
  • ✓ Tutarlı davranış göstermeli

⚠️ Riskler ve Dikkat Edilecekler

🔴 Yüksek Risk: Desktop'ta Bozulma

Body overflow-hidden kaldırınca desktop'ta layout bozulabilir.

Önlem: Desktop'ta body'ye overflow-y: auto ekle, mobilde overflow: visible yap.

🟡 Orta Risk: Grid Layout Değişiklikleri

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.

🟡 Orta Risk: Gradient Background

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.

🟢 Düşük Risk: Modal/Overlay Scroll Lock

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).

🎯 Özet ve Sonuç

Ana Sorun

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.

Kök Sebep

Over-engineering: Scroll için çok fazla katman ve kontrol mekanizması var. Basit scroll sistemini kompleks hale getirmişiz.

Çözüm Stratejisi

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.

Beklenen Sonuç

  • ✅ Mobilde scroll her zaman çalışacak
  • ✅ iOS Safari'de smooth momentum scroll
  • ✅ Mobile menu/modal scroll'u engellemeyecek
  • ✅ Player bar touch event'leri izole edilecek
  • ✅ "10 kerede 4 kere" sorunu tamamen ortadan kalkacak

Tahmini Süre

Implementation: 2-3 saat

Testing: 1-2 saat

Toplam: 3-5 saat (tek bir oturumda bitirilebilir)

Next Steps

  1. Kullanıcıdan onay al
  2. Git checkpoint oluştur (geri dönüş için)
  3. Sırayla çözümleri uygula
  4. Her adımda test et
  5. Son test senaryolarını çalıştır
  6. Production'a deploy

🤖 Bu rapor Claude AI (Sonnet 4.5) tarafından oluşturuldu

Claude AI | Muzibu.com.tr