Stacking context là một nhóm xếp chồng độc lập: mọi so sánh z-index chỉ diễn ra bên trong nó, và cả nhóm được xếp như một khối duy nhất so với bên ngoài.
Cái gì tạo ra nó:
- element gốc <html>
- position khác static kèm z-index khác auto
- opacity nhỏ hơn 1
- transform, filter, backdrop-filter, perspective, mix-blend-mode khác normal
- will-change với bất kỳ giá trị nào tạo layer
- isolation: isolate, contain: layout | paint | strict
- flex/grid item có z-index khác auto
<div class="a"> <!-- opacity: .99 → tạo stacking context, z-index nội bộ: 1 -->
<span style="z-index: 9999">A1</span>
</div>
<div class="b" style="position:relative; z-index:2">B</div>
<!-- B luôn nằm trên A1, vì so sánh diễn ra ở cấp .a vs .b -->Hai thứ hay gây bất ngờ vì không ai nghĩ chúng liên quan tới z-index: opacity: 0.99 (hay dùng để ép GPU) và transform (hay dùng cho animation).
.component { isolation: isolate; } /* nhốt z-index bên trong, không rò ra ngoài */Chốt khi debug: z-index không chạy thì đừng tăng số — đi ngược lên cây DOM tìm tổ tiên đầu tiên tạo stacking context, vấn đề nằm ở đó.