Prompt dan Konteks Berkaitan
Halaman produk mempunyai pengepala melekat (sticky header) dan kad yang mengandungi butang menu. Menu tersebut diletakkan secara mutlak (absolutely positioned) dan diberikan nilai susunan bertindih (stacking value) yang amat besar. Apabila ia dibuka berhampiran bahagian atas halaman, pengepala masih melukis di atasnya. Apabila ia melebihi sempadan kad, bahagian bawahnya hilang. Seorang rakan sepasukan mencadangkan penambahan satu lagi sifar pada nilai susunan tersebut.
Terangkan mengapa cadangan itu tidak dapat membetulkan kedua-dua simptom. Diagnosis contoh di bawah, bezakan susunan lukisan (paint order) daripada pemotongan (clipping) dan geometri kedudukan, serta pilih pembaikan tahan lama untuk tiga kes: menu yang boleh kekal di dalam komponennya, overlay yang mesti keluar daripada komponen, dan UI yang semantiknya memerlukan dialog modal atau popover.
<header class="site-header">Navigation</header>
<main class="page">
<section class="card">
<button type="button">Open menu</button>
<div class="menu">Menu items</div>
</section>
</main>.site-header {
position: sticky;
top: 0;
z-index: 4;
}
.page {
position: relative;
z-index: 1;
}
.card {
position: relative;
overflow: hidden;
transform: translateZ(0);
}
.menu {
position: absolute;
inset-block-start: 100%;
z-index: 999999;
}Anggap pelayar evergreen terkini. Jawapan hendaklah mengekalkan tingkah laku tatalan, containment, dan kebolehcapaian (accessibility) yang disengajakan dan bukannya memadam CSS sehingga tangkapan skrin kelihatan betul.
Perkara yang Dinilai oleh Penemu Bual
Isyarat pertama ialah sama ada calon mengetahui sempadan perbandingan. Stacking context dilukis sebagai satu unit atom dalam konteks induknya. Elemen keturunan boleh menyusun semula diri mereka di dalam unit tersebut, tetapi tiada nilai susunan keturunan yang boleh menaikkan seluruh unit di atas elemen adik-beradik (sibling) kepada induknya. Di sini, nilai besar menu menang di dalam .page; .page secara keseluruhannya masih mengambil bahagian pada tahap 1, di bawah pengepala pada tahap 4.
Isyarat kedua ialah pengelasan. "Di belakang pengepala" ialah masalah susunan lukisan (paint order). "Terpotong pada tepi kad" ialah masalah pemotongan (clipping) yang disebabkan oleh overflow: hidden. Kategori ketiga sering kelihatan serupa: leluhur dengan transform mewujudkan containing block untuk keturunan dengan kedudukan absolute dan fixed, jadi koordinat atau tingkah laku fixed mungkin relatif kepada leluhur yang tidak dijangka. Nilai susunan tunggal tidak membaiki pemotongan atau geometri.
Isyarat ketiga ialah pengetahuan tentang pencipta konteks tanpa menjadikan jawapan sekadar senarai yang dihafal. Punca biasa termasuk elemen berkedudukan dengan nilai susunan bukan auto, kedudukan fixed atau sticky, kelegapan (opacity) di bawah satu, transforms, filters, perspective, pemotongan atau penopengan (masking), blending, isolation: isolate, layout atau paint containment, container queries, dan anak flex atau grid dengan nilai susunan bukan auto. Kemahiran yang berguna adalah mencari sempadan relevan yang pertama pada setiap rantaian leluhur.
Isyarat keempat ialah pertimbangan pembaikan. Mengalih keluar konteks yang tidak disengajakan, menukar tahap leluhur yang betul, menukar induk (reparenting) sesuatu overlay, dan menggunakan top layer pelayar menyelesaikan kontrak yang berbeza. Portal menukar keturunan DOM dan boleh melepasi pemotongan komponen, tetapi ia tidak secara automatik memasuki top layer atau menambah tingkah laku modal, fokus, penutupan (dismissal), atau nama yang boleh diakses.
Isyarat terakhir ialah pengesahan. Pemeriksaan DevTools harus disokong oleh ujian pertindihan yang boleh diperhatikan, penatalan, pemeriksaan saiz semula dan zum, penggunaan papan kekunci, serta kewujudan bersama dengan overlay lain. Pembetulan tidak lengkap jika ia menang dalam satu tangkapan skrin tetapi merosakkan bekas tatal (scroll container), berlabuh pada sistem koordinat yang salah, atau membiarkan menu biasa menutup modal sebenar.
Soalan untuk Dijelaskan Sebelum Menjawab
- Piksel manakah yang salah? Adakah menu dilukis di bawah elemen lain, terpotong pada sempadan, diletakkan pada koordinat yang salah, atau ditutup oleh elemen top layer? Ini memerlukan pembetulan yang berbeza.
- Leluhur manakah yang mencipta konteks? Periksa kedua-dua rantaian menu dan rantaian elemen yang menutupnya. Perbandingan yang menentukan ialah tempat rantaian pertama kali menjadi adik-beradik (siblings), bukan semestinya pada dua elemen yang kelihatan.
- Adakah pemotongan (clipping) disengajakan? Sesebuah kad mungkin memotong media berbucu bulat, dan bekas tatal mungkin memerlukan tingkah laku overflow. Mengalih keluarnya secara global boleh membetulkan menu sambil merosakkan susun atur dan penatalan.
- Pada apakah overlay harus dilabuhkan? Menukar induk kepada akar overlay yang dikongsi bermakna koordinatnya mesti diukur relatif kepada akar tersebut dan dikemas kini semasa tatal, saiz semula, zum, dan perubahan susun atur.
- Adakah UI memerlukan semantik top layer? Dialog modal harus menyekat interaksi luar dan mengurus fokus. Menu yang ringan mungkin hanya memerlukan akar overlay. Popover yang sesuai boleh menggunakan tingkah laku popover platform dan penempatan top layer.
- Overlay manakah yang boleh wujud bersama? Tentukan sama ada menu, tooltip, navigasi melekat, drawer, dan modal boleh bertindih. Set kecil lapisan bernama lebih mudah difahami berbanding nilai enam digit yang rawak.
- Kontrak pelayar dan komponen apakah yang terpakai? Primitif platform semasa mungkin lebih diutamakan; paparan web (webview) lama atau primitif sistem reka bentuk yang sedia ada mungkin mengubah pilihan pelaksanaan.
Rangka Kerja Jawapan 30 Saat
"Saya akan mengelaskan kegagalan tersebut sebelum menukar nilai. 999999 menu hanya dibandingkan di dalam stacking context miliknya sendiri. Leluhurnya .page berada pada tahap 1, jadi seluruh subpokok kekal di bawah pengepala melekat pada tahap 4. Secara berasingan, limpahan tersembunyi (hidden overflow) kad memotong menu, dan transform miliknya boleh mengubah containing block menu. Saya akan memeriksa rantaian leluhur dan elemen paling atas sebenar pada titik pertindihan. Jika menu boleh kekal setempat, saya akan mengalih keluar konteks yang tidak disengajakan atau menaikkan leluhur yang betul dan mengendalikan pemotongan secara setempat. Jika ia mesti keluar, saya akan me-rendernya dalam akar overlay yang dikongsi dan mengira semula geometri penambat. Jika interaksi tersebut ialah modal atau popover yang sesuai, saya akan menggunakan top layer pelayar dan melaksanakan kontrak fokus serta penutupan yang diperlukan. Kemudian saya akan menguji tatal, saiz semula, zum, interaksi papan kekunci, dan kewujudan bersama dengan overlay lain."
Huraian Mendalam Langkah demi Langkah
Mulakan dengan memisahkan empat mekanisme. Ia boleh gagal bersama, tetapi ia tidak boleh saling ditukar ganti:
PAINT ORDER
Which painted box is above another?
Controlled by the stacking-context tree and paint order inside each context.
CLIPPING
Which pixels are allowed to appear?
Controlled by overflow, clip paths, masks, and paint containment.
GEOMETRY
Which box supplies the coordinate system?
A transform can establish the containing block for absolute and fixed descendants.
TOP LAYER
Is the element outside normal document stacking?
Modal dialogs and shown popovers can be placed in the browser-managed top layer.Bina pepohon konteks untuk contoh ini dan bukannya membandingkan dua nombor yang kelihatan. Pengepala melekat mencipta konteks pada tahap 4. .page yang berkedudukan mencipta konteks adik-beradik pada tahap 1. Transform kad mencipta satu lagi konteks di dalam .page. Nilai besar menu hanya menyusunnya di dalam subpokok tersebut. Dari segi konsep, perbandingannya ialah header: 4 berbanding page: 1; ia tidak pernah menjadi header: 4 berbanding menu: 999999.
Seterusnya, periksa pemotongan secara bebas. Menu ialah keturunan kepada .card, jadi piksel di luar kotak padding kad dipotong oleh limpahan tersembunyi (hidden overflow). Pertindihan mengubah susunan lukisan; ia tidak memperluas kawasan pemotongan. Menaikkan .page, mengalih keluar transform, atau menukar nilai menu boleh meletakkannya di atas pengepala tetapi masih membiarkan bahagian bawahnya terpotong.
Kemudian periksa containing block. Menu adalah absolute, jadi kad yang berkedudukan sudah membekalkan koordinatnya. Transform adalah lewah (redundant) untuk menu khusus ini, tetapi ia menjadi penting jika pelaksanaan masa hadapan menukar menu kepada position: fixed: leluhur yang diubah (transformed) boleh menjadikan elemen "fixed" itu bertindak relatif kepada leluhur dan bukannya viewport. Inilah sebabnya menukar absolute kepada fixed bukanlah jalan keluar yang boleh dipercayai.
Gunakan pemeriksaan pelayar untuk mengesahkan hipotesis dan bukannya meneka. Periksa gaya yang dikira (computed styles) pada setiap leluhur sehingga pencipta konteks dan leluhur pemotong yang pertama ditemui. Bandingkan rantaian konteks menu dan pengepala. Pada koordinat di mana kedua-duanya bertindih, buat pertanyaan tentang apa yang dianggap paling atas oleh ujian hit (hit testing):
function inspectOverlap(x, y) {
const stack = document.elementsFromPoint(x, y)
return stack.map((element) => ({
element,
position: getComputedStyle(element).position,
zIndex: getComputedStyle(element).zIndex,
overflow: getComputedStyle(element).overflow,
transform: getComputedStyle(element).transform,
}))
}elementsFromPoint() mudah digunakan untuk melihat tindanan ujian hit; elementFromPoint() hanya mengembalikan elemen teratas yang layak. Ujian hit ialah bukti sokongan, bukan penyahpepijat stacking context yang lengkap: elemen dengan pointer-events: none mungkin dilangkau, dan geometri pemotongan atau di luar skrin masih memerlukan pemeriksaan susun atur.
Pilih pembaikan terkecil yang sepadan dengan sempadan pemilikan.
Bagi menu setempat, alih keluar konteks yang tidak disengajakan jika ia tidak mempunyai kesan visual atau containment yang diperlukan. Jika halaman benar-benar memerlukan konteksnya, bandingkan dan tukar token peringkat halaman kerana itulah adik-beradik yang sedang disusun berbanding pengepala. Jika pemotongan kad hanya untuk media, letakkan pemotongan itu pada pembungkus media bersarang (nested media wrapper) dan bukannya pada keseluruhan kad interaktif.
:root {
--layer-content: 0;
--layer-sticky: 20;
--layer-overlay: 40;
}
.page {
position: relative;
z-index: var(--layer-content);
}
.site-header {
z-index: var(--layer-sticky);
}
.card-media {
overflow: hidden;
border-radius: 1rem;
}
.menu {
z-index: var(--layer-overlay);
}Ini hanya berfungsi apabila kontrak yang dimaksudkan membenarkan subpokok halaman kekal di bawah pengepala dan menu tidak perlu melintasi sempadan tersebut. Jika menu mesti menutup pengepala, keputusan lapisan adalah milik leluhur sepunya atau overlay mesti beralih ke akar yang dikongsi.
Bagi overlay yang boleh diguna semula yang mesti melepasi konteks dan pemotongan setempat, render ia di bawah akar overlay yang dikongsi berhampiran akar dokumen. Kekalkan pencetus (trigger) sebagai pemilik logiknya, kekalkan hubungan yang boleh diakses, dan kira panel daripada segi empat tepat pencetus. Kira semula apabila penatalan, penukaran saiz, zum, atau perubahan susun atur mengubah mana-mana segi empat tepat. Pengendalian perlanggaran mesti mengambil kira tepi viewport dan arah penulisan. Menukar induk tanpa pemilikan geometri menukar pepijat pemotongan kepada pepijat menu yang hanyut (drifting menu).
Bagi dialog modal sebenar, utamakan elemen dialog asli yang dibuka secara modal atau primitif boleh diakses yang mapan yang menyediakan kontrak yang sama. Bagi interaksi bukan modal yang sesuai, API popover boleh meletakkan kandungan yang dipaparkan dalam top layer. Entri top layer dirender di atas konteks dokumen biasa; entri yang lebih lewat berada di atas entri yang lebih awal, dan setiap satunya mempunyai konteks akar tersendiri. Limpahan leluhur, kelegapan, topeng (masks), dan transform tidak menarik elemen top layer kembali ke dalam konteks dokumen leluhur.
Top layer bukanlah "z-index yang lebih kuat" yang universal. Ia merupakan lapisan teratur yang diuruskan oleh pelayar dengan mekanisme masuk dan keluar secara semantik. Modal masih memerlukan nama yang berguna, fokus awal yang disengajakan, interaksi yang dibendung (contained), dasar penutupan, dan pemulihan fokus. Menu masih memerlukan semantik menu atau penzahiran (disclosure) serta tingkah laku papan kekunci yang betul. Memilih lapisan tidak pernah menggantikan pemilihan model interaksi.
Sahkan pembaikan sebagai satu matriks:
- Buka berhampiran setiap tepi viewport dan di dalam bekas tatal bersarang.
- Tatal halaman dan bekas terdekat; sahkan panel kekal berlabuh atau ditutup mengikut dasar.
- Saiz semula, zum kepada 200%, dan uji susun atur sempit dan lebar.
- Navigasi menggunakan papan kekunci; sahkan susunan, fokus kelihatan, Escape, dan pemulangan fokus sepadan dengan komponen.
- Buka ia dengan navigasi melekat, drawer, tooltip, dan modal sebenar yang sudah sedia ada.
- Periksa ujian hit pada piksel yang terlindung dan sahkan tiada overlay tidak kelihatan yang memintas kawalan yang tidak berkaitan.
- Uji label terjemahan yang panjang serta susun atur kiri-ke-kanan dan kanan-ke-kiri apabila disokong.
- Sahkan bahawa limpahan, containment, penggubahan (compositing), dan tingkah laku tatal yang disengajakan masih berfungsi.
Contoh Jawapan Berkualiti Tinggi
"Nilai yang besar sedang dibandingkan pada tahap yang salah. Menu berada di dalam stacking context .page, yang mengambil bahagian pada tahap 1. Pengepala ialah konteks adik-beradik pada tahap 4. Pelayar melukis subpokok halaman secara atomik di bawah pengepala, jadi nilai keturunan 999999 tidak boleh keluar dan bersaing dengan pengepala.
Terdapat juga kegagalan pemotongan (clipping) yang berasingan. Limpahan tersembunyi (hidden overflow) kad membuang piksel di luar sempadannya; z-index menukar susunan tetapi tidak boleh membesarkan keratan tersebut. Transform kad mencipta satu lagi konteks dan boleh membentuk containing block untuk keturunan absolute dan fixed, jadi beralih kepada kedudukan fixed mungkin masih menggunakan sistem koordinat yang tidak dijangka.
Saya akan memeriksa kedua-dua rantaian leluhur dalam DevTools, mengenal pasti pencipta konteks dan pemotongan yang pertama, dan memeriksa tindanan ujian hit pada koordinat pertindihan. Bagi menu setempat, saya hanya akan mengalih keluar konteks yang tidak disengajakan, memindahkan pemotongan ke pembungkus media, atau melaraskan lapisan bernama pada leluhur sepunya yang sebenarnya sedang dibandingkan. Saya tidak akan terus meningkatkan nilai daun (leaf value).
Jika menu dibenarkan mengikut kontrak untuk melintasi sempadan komponen dan pengepala, saya akan me-rendernya dalam akar overlay yang dikongsi. Ini bermakna sistem overlay memiliki pengukuran, pengendalian perlanggaran, dan kemas kini semasa tatal, saiz semula, zum, dan perubahan susun atur. Portal membantu dengan keturunan dan pemotongan, tetapi ia tidak mencipta tingkah laku top layer atau kebolehcapaian.
Jika interaksi tersebut ialah dialog modal, saya akan menggunakan tingkah laku dialog modal asli atau primitif boleh diakses yang telah diuji. Jika ia adalah popover yang sesuai, saya akan mempertimbangkan tingkah laku popover platform. Kedua-duanya boleh menggunakan top layer pelayar, tetapi saya masih akan melaksanakan kontrak nama boleh diakses, fokus, papan kekunci, penutupan, dan pemulihan yang betul. Akhir sekali, saya akan mengesahkan bekas tatal, tepi viewport, zum 200%, penggunaan papan kekunci, susun atur terjemahan, ujian hit, dan kewujudan bersama dengan overlay lain."
Kesilapan Lazim
- Meningkatkan nilai keturunan tanpa henti → ia kekal terperangkap dalam konteks induk yang lebih rendah → Bandingkan konteks adik-beradik yang pertama dan tukar pemilik keputusan lapisan tersebut.
- Menganggap setiap piksel tersembunyi sebagai pepijat susunan (stacking bug) → limpahan atau paint containment masih memotongnya → Periksa leluhur pemotongan secara berasingan daripada susunan lukisan.
- Menukar kedudukan absolute kepada fixed → leluhur yang mengalami transform mungkin masih mentakrifkan containing block → Jejak sistem koordinat sebelum memilih mod kedudukan.
- Mengalih keluar setiap pengisytiharan transform atau overflow → media berbucu bulat, penatalan, containment, atau tingkah laku render menjadi rosak → Alih keluar hanya pencetus yang tidak disengajakan atau sempitkannya kepada elemen yang memerlukannya.
- Menggunakan portal untuk memindahkan setiap overlay ke body → masalah penambatan, perlanggaran, pemilikan, dan fokus menggantikan pepijat asal → Gunakan sistem overlay yang dikongsi dengan kontrak geometri dan interaksi yang jelas.
- Menganggap portal adalah top layer → konteks dokumen biasa masih boleh menutupnya → Gunakan primitif top layer platform apabila semantiknya sesuai.
- Menggunakan dialog modal untuk setiap panel terapung → fokus dan interaksi luar disekat tanpa keperluan → Pilih modal, popover, menu, tooltip, atau penzahiran sebaris (inline disclosure) berdasarkan tingkah laku terlebih dahulu.
- Mencipta nilai global yang rawak → komponen memasuki pertandingan peningkatan lapisan yang tidak terkawal → Gunakan set kecil lapisan bernama dan kekalkan nilai setempat secara setempat.
- Hanya mengesahkan satu tangkapan skrin → tatal, zum, papan kekunci, atau overlay lain memperkenalkan semula kegagalan tersebut → Uji matriks pertindihan dan interaksi.
Soalan Susulan dan Maklum Balas
Adakah z-index yang lebih besar sentiasa meletakkan elemen di atas elemen yang lebih kecil?
Hanya apabila nilai tersebut mengambil bahagian dalam perbandingan stacking context relevan yang sama. Keturunan disusun di dalam konteks mereka, dan keseluruhan konteks itu kemudiannya disusun dalam induknya. Bandingkan rantaian konteks, bukan nilai terkira (computed values) yang terasing.
Sifat CSS manakah yang biasanya mencipta stacking context?
Akar, kedudukan fixed atau sticky, elemen berkedudukan dengan nilai susunan bukan auto, kelegapan di bawah satu, transforms, filters, perspective, pemotongan atau penopengan (masking), blending, isolation, sifat containment dan container-query yang terpilih, serta anak flex atau grid dengan nilai susunan bukan auto adalah punca biasa. Senarai tepat sentiasa berkembang, jadi pemeriksaan harus mengenal pasti pencetus terkira dan bukannya hanya bergantung pada ingatan.
Mengapa elemen boleh berada di atas adik-beradiknya tetapi masih kelihatan terpotong?
Susunan lukisan (paint order) menentukan piksel mana yang dibenarkan untuk dilukis paling akhir. Kawasan pemotongan menentukan piksel mana yang dibenarkan wujud. Memenangi susunan lukisan tidak dapat memulihkan piksel yang telah dibuang oleh overflow, clip-path, topeng, atau paint containment milik leluhur.
Adakah position: fixed sentiasa dapat melepasi leluhur yang mempunyai overflow-hidden?
Tidak. Kedudukan fixed mengubah tingkah laku containing block yang normal, tetapi transforms dan sifat berkaitan pada leluhur boleh membentuk containing block tersebut. Mekanisme pemotongan lain masih boleh terpakai. Jejak geometri dan pemotongan dan bukannya menggunakan kedudukan fixed sebagai jalan keluar universal.
Adakah rendering melalui portal menyelesaikan keseluruhan masalah?
Ia boleh melepasi keturunan DOM, konteks, dan pemotongan setempat jika akar sasaran berada di luar semua itu. Ia juga memerlukan pemilikan baharu bagi pengukuran, kemas kini tatal, pengendalian perlanggaran, hubungan acara, fokus, dan penutupan. Ia kekal dalam susunan dokumen biasa melainkan primitif itu sendiri memasuki top layer.
Bagaimanakah top layer berbeza daripada token lapisan global yang sangat tinggi?
Elemen top layer dilukis dalam lapisan teratur yang diuruskan oleh pelayar di atas kandungan dokumen biasa dan mencipta stacking context akar. Susunan kemasukan menentukan susunan dalam lapisan tersebut. Token global yang tinggi masih mengambil bahagian dalam pepohon konteks dokumen dan boleh kekal terperangkap oleh leluhur.
Patutkah sesebuah pasukan mengharamkan semua nilai z-index setempat?
Tidak. Nilai setempat berguna untuk menyusun bahagian di dalam satu komponen, seperti lencana di atas imej. Gunakan skala bernama yang kecil hanya pada sempadan yang dikongsi seperti navigasi melekat, overlay yang boleh diguna semula, dan drawer. Sempadan tersebut, bukannya saiz nombor, yang menentukan sama ada sesuatu nilai adalah global.
Bagaimanakah anda akan menghalang regresi kelas ini?
Dokumenkan beberapa pemilik lapisan yang dikongsi, pusatkan penempatan overlay yang boleh diguna semula, dan tambah story interaksi yang menggabungkan kandungan melekat, bekas tatal, menu, dan modal. Sahkan penempatan tepi, tatal, zum, tingkah laku papan kekunci, dan satu lagi overlay yang aktif; tangkapan paparan statik sahaja tidak dapat membuktikan kontrak tersebut.