Vì z-index chỉ so sánh trong cùng một stacking context. Nếu tổ tiên của dropdown tạo ra một stacking context, cả cây con bị "đóng gói" và xếp lớp như một khối theo z-index của tổ tiên đó — 9999 bên trong không vượt qua được ngưỡng của khối chứa nó.
Những thuộc tính tạo stacking context (hay bị bỏ sót):
- position khác static kèm z-index khác auto.
- opacity < 1, transform, filter, backdrop-filter, perspective, mask, mix-blend-mode khác normal.
- will-change trỏ tới một trong các thuộc tính trên, isolation: isolate, contain: paint.
- Là flex/grid item và có z-index khác auto.
Cách xử lý theo thứ tự ưu tiên:
1. Tìm tổ tiên gây ra context (DevTools tab Layers, hoặc soi transform/opacity trên đường đi lên) và bỏ thuộc tính đó nếu không cần.
2. Nâng z-index của chính tổ tiên đó, không phải của dropdown.
3. Đưa lớp nổi ra ngoài cây bằng portal vào body.
4. Dùng Popover API hoặc <dialog>: nội dung lên top layer, nằm trên mọi stacking context và không cần z-index.
Mẹo phòng ngừa: đặt isolation: isolate có chủ đích ở gốc từng khối UI để giữ z-index cục bộ, thay vì leo thang số.