Performa · 2 menit baca · 19 Oktober 2026

Compositor iOS Safari mengabaikan z-index kamu

Gambar sticky menembus konten yang seharusnya menutupinya, hanya di iPhone. Menaikkan z-index tidak membantu, karena masalahnya ada di urutan paint antar-layer GPU.

Ponsel kartun di mana kartu gambar keliru menimpa kartu header di atasnya
15–18
versi iOS tempat bug ini tercatat di catatan saya
1
deklarasi CSS yang memperbaikinya
0
kali isolation: isolate membantu

01 · Bug-nya

Di desktop aman. Di Chrome aman. Di iPhone tidak.

Situs klien ini punya gambar samping yang sticky. Konten yang di-scroll di atasnya punya z-index lebih tinggi, jadi seharusnya menutupi gambar itu. Di iOS Safari, gambarnya tetap menembus.

02 · Kenapa z-index tidak menolong

Safari memindahkan elemen sticky ke layer GPU tersendiri.

Safari tidak menghormati z-index antara elemen yang punya layer sendiri dan elemen di sebelahnya yang tidak. Jadi ini bug urutan gambar di compositor, bukan bug stacking context. Itu sebabnya isolation: isolate tidak berpengaruh. Properti itu hanya mengatur stacking context.

03 · Perbaikannya

Beri tetangganya layer juga.

Wrapper konten sudah punya position: relative dan z-index. Dengan tambahan transform 3D, wrapper itu ikut mendapat layer, dan Safari menggambar keduanya dengan urutan yang benar. will-change: transform juga bisa, tapi hasilnya kurang konsisten di Safari versi lama.

.content {
  position: relative;
  z-index: 2;
  /* composite layer ini juga, supaya iOS Safari menggambarnya di atas gambar sticky */
  transform: translate3d(0, 0, 0);
}

04 · Jebakan minifier

Proses build bisa membatalkan perbaikan ini.

Beberapa minifier menulis ulang translate3d(0,0,0) menjadi translate(0). Versi 2D itu tidak membuat layer. Di Tailwind, tulis sebagai arbitrary property (transform:translate3d(0,0,0) di dalam kurung siku) supaya tidak diubah. Lalu cek CSS hasil build, jangan hanya source-nya.

05 · Bug lain yang mirip

Gambar yang berkedip atau belepotan adalah masalah yang berbeda.

Perbaikannya tergantung kasusnya:

  • container sticky dengan gambar object-cover: pasang -webkit-transform: translateZ(0) di container-nya
  • carousel, atau elemen yang diputar sekaligus di-scale: pakai will-change: transform
  • selalu tulis width dan height gambar
  • transisikan opacity dan transform, jangan all
  • overflow: hidden dengan anak yang di-scale: pasang will-change di parent-nya

Pastikan dulu bug mana yang kamu hadapi sebelum mengubah CSS.

06 · Cek di iPhone sungguhan

Emulator tidak akan memperlihatkan bug ini.

Tes langsung di iOS Safari. Catatan saya menyebut versi yang lebih baru sudah memperbaikinya. Jadi, cek di perangkat yang benar-benar dipakai pengguna kamu, jangan berasumsi.

Tulisan berikutnyaFavicon yang dirusak OpenNext