У меня есть следующий простой компонент заголовка с элементами навигации, который при наведении должен добавить следующие два правила css к элементу mega-menu div, чтобы он отображался:
visibility: visible;
opacity: 1;
.nav-menu {
min-height: 112px;
padding-left: 5.6rem;
padding-right: 5.6rem;
background-color: green;
display: flex;
gap: 24px;
align-items: center;
justify-content: center;
}
.nav-menu li {
list-style: none;
}
.nav-menu li a {
color: white;
text-decoration: none;
}
.nav-menu li a:hover{
text-decoration: underline;
}
.mega-menu {
visibility: hidden;
opacity: 0;
position: absolute;
background-color: lightblue;
width: 100%;
min-height: 250px;
top: 128px;
text-align: center;
}
.nav-menu li a:hover .mega-menu {
visibility: visible;
opacity: 1;
}<div class = "container">
<ul class = "nav-menu">
<li>
<a href = "#">Navigation item</a>
</li>
<li>
<a href = "#">Navigation item</a>
</li>
<li>
<a href = "#">Navigation item</a>
</li>
<li>
<a href = "#">Navigation item</a>
</li>
<li>
<a href = "#">Navigation item</a>
</li>
</ul>
<div class = "mega-menu">
This mega menu should only be visible when one of the list items in the nav
menu is hovered on (and then once open will close when no longer hovering on
the mega menu)
</div>
</div>Однако, как видно из моего фрагмента, я изо всех сил пытаюсь обновить класс mega-menu, когда зависает a в nav-menu. В идеале мегаменю должно быть видно при наведении курсора на элемент списка или когда пользователь наводит курсор на мегаменю (в противном случае оно не должно быть видно).
Любые указатели относительно того, где я ошибаюсь, будут действительно оценены.
Я пропустил родительский контейнер из фрагмента, чтобы уменьшить лишний код из фрагмента, но предположил, что контекст ясен, будет обновлен. Спасибо!
Кроме того, вы даже не использовали какой-либо родственный комбинатор с самого начала — a:hover .mega-menu повлияет на элемент .mega-menu, который является потомком зависшей ссылки.
Этот родительский контейнер по-прежнему не создает ссылки и .mega-menu братьев и сестер.






Один из способов сделать это с помощью только CSS — использовать селектор has в общем контейнере, например:
.container:has(a:hover) .mega-menu{
visibility: visible;
opacity: 1;
}
Проблема в том, что сейчас селектор has недоступен во всех браузерах, например, Firefox еще не реализует его.
Это можно сделать без использования :has() (который по-прежнему не поддерживается в FIrefox, если только пользователь явно не включил его) и без JavaScript.
Прежде всего, .mega-menu является братом UL, поэтому мы используем .nav-menu:hover + .mega-menu в качестве селектора, чтобы сделать его видимым при наведении курсора на UL.
Но вы, вероятно, не хотите, чтобы он отображался уже при наведении курсора на сам список, а только тогда, когда наводится один из фактических элементов навигации?
Здесь этого можно добиться, поместив pointer-events: none на UL и «обратив» это снова с помощью pointer-events: all на LI.
.nav-menu {
min-height: 112px;
padding-left: 5.6rem;
padding-right: 5.6rem;
background-color: green;
display: flex;
gap: 24px;
align-items: center;
justify-content: center;
pointer-events: none;
}
.nav-menu li {
list-style: none;
pointer-events: all;
}
.nav-menu li a {
color: white;
text-decoration: none;
}
.nav-menu li a:hover{
text-decoration: underline;
}
.mega-menu {
visibility: hidden;
opacity: 0;
position: absolute;
background-color: lightblue;
width: 100%;
min-height: 250px;
top: 128px;
text-align: center;
}
.nav-menu:hover + .mega-menu {
visibility: visible;
opacity: 1;
}<div class = "container">
<ul class = "nav-menu">
<li>
<a href = "#">Navigation item</a>
</li>
<li>
<a href = "#">Navigation item</a>
</li>
<li>
<a href = "#">Navigation item</a>
</li>
<li>
<a href = "#">Navigation item</a>
</li>
<li>
<a href = "#">Navigation item</a>
</li>
</ul>
<div class = "mega-menu">
This mega menu should only be visible when one of the list items in the nav
menu is hovered on (and then once open will close when no longer hovering on
the mega menu)
</div>
</div>Кстати, вы можете избежать использования этого «магического числа» top: 128px; (что может быть проблематично, если UL не всегда был таким высоким, как вы ожидали, например, из-за различий в реальных шрифтах, используемых для рендеринга этого на клиенте), если вы сделаете контейнер точкой отсчета, добавив к нему position: relative, а затем используя top: 100%.
Спасибо, это действительно исчерпывающе и полезно. Единственная оставшаяся проблема заключается в том, что пользователь не может взаимодействовать с мегаменю. Из-за ограниченной высоты наводимой области элементов списка в nav-menu - мегаменю не остается видимым, пока пользователь переходит от наведения на ссылки к наведению на само мегаменю.
Да все верно. Но у вас уже была бы такая же проблема, если бы действительно был способ показать этот элемент, основываясь только на a:hover здесь. Вам просто нужно будет сделать пункты меню достаточно высокими, чтобы они достигали нижнего угла UL. «Пробелы» для того, чтобы курсор мыши попадал между запускающим элементом и целью, редко являются хорошей идеей.
(Или вы можете использовать псевдоэлемент, который только «расширяет» область наводимой ссылки до нижней части UL, когда ссылка наводится.)
Похоже, вы не поняли значения слова "брат".