Выпадающее меню прячется под блоком
Вопрос
Выпадающее меню прячется под соседним блоком, хотя у него z-index: 1000. Как будешь разбираться?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Проверить, что у меню есть `position` (или оно flex/grid-элемент), иначе `z-index` не работает
Найти ближайшего предка, создающего контекст наложения (`z-index`, `transform`, `opacity`, `filter`)
Сравнивать уровни нужно у предков в общем контексте, а не у меню и соседа
Проверить `overflow: hidden` у предков: меню может быть обрезано, а не перекрыто
Решение: поднять контекст предка, убрать лишний контекст или вынести меню в портал
Завести шкалу уровней (токены) вместо гонки чисел
Что могут спросить следом
- Как найти, кто создал контекст наложения, в DevTools?
- Чем поможет
isolation: isolate? - Как top layer у
<dialog>и popover решает эту проблему?
Разбор
Сначала проверяю, что меню вообще позиционировано, иначе его z-index игнорируется. Дальше иду вверх по предкам и ищу, кто создаёт контекст наложения: позиционированный элемент с z-index, transform, opacity меньше единицы, filter. Если такой предок есть, меню заперто внутри него, и его 1000 сравнивается только с соседями внутри. Снаружи сравниваются уже уровни предков в общем контексте, и если предок ниже соседнего блока, меню проиграет при любом числе. Ещё отдельно проверяю overflow: hidden у обёрток: тогда меню не перекрыто, а обрезано, и z-index вообще ни при чём. Решения: поднять уровень нужного предка, убрать случайный контекст вроде ненужного transform, или отрендерить меню в портал в конце body. Для нативных попапов есть <dialog> и атрибут popover, они попадают в top layer поверх всего. И в проекте завожу шкалу уровней в переменных, чтобы не было гонки девяток.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.