Reputation: 680
My menu is placed vertically on the left side of the page and between the <li>
I have an :after
that is a separator. What I want to have is to hide the after element when I hover the element itself (if it's the first element) or the above and the bottom one when it's the middle one and if it's the last child just the :after
element of the previous <li>
. This may sound confusing but here is my code:
.menu {
float: left;
color: white;
}
.menu > ul {
list-style: none;
text-align: center;
padding: 0;
margin: 0;
}
.menu > ul > li {
display: block;
position: relative;
padding: 60% 5px;
background-color: #048990;
cursor: pointer;
transition: all 0.5s;
}
.menu > ul > li:hover {
background-color: #444;
color: white;
}
.menu > ul > li:hover .menu > ul > li::after {
opacity: 0;
}
.menu > ul > li:active {
background-color: #444;
}
.menu >ul >li:after {
content: "";
background: #FFF;
position: absolute;
bottom: 0;
left: 7%;
height: 1px;
width: 86%;
}
.menu > ul > li:last-child:after {
display: none;
}
<div class="menu">
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
Now all I want to do is something like this:
.menu > ul > li:hover + .menu > ul > li::after
{
opacity: 0;
}
But it's not working. Any help would be appreciated.
Upvotes: 4
Views: 4218
Reputation: 89750
The below selector would not work because the full selector should not be repeated when using +
adjacent sibling combinator. This would try to select the li::after
that is under .menu > ul
which is in-turn the adjacent sibling of the li
that is being hovered on.
.menu > ul > li:hover + .menu > ul > li::after {
opacity: 0;
}
It should instead be written as .menu > ul > li:hover::after
if you want to select the ::after
of the li
that is being hovered on (or) as .menu > ul > li:hover + li::after
if you want to select the ::after
element of the li
that is the adjacent sibling of the li
which is being hovered on.
The other problem with the approach that you are using currently is that CSS selectors can be used only to select the children, descendants or the siblings that appear after the current element in DOM. They cannot be used to target the previous siblings and so if the ::after
of each element is used to create the separator then the separator on top can never be hidden.
Instead, we can use the ::before
elements (on all but the first-child
) to create the separator. In this scenario we can use CSS selectors to hide both the the current element's ::before
and the next element's ::before
on hover.
.menu {
float: left;
color: white;
}
.menu > ul {
list-style: none;
text-align: center;
padding: 0;
margin: 0;
}
.menu > ul > li {
display: block;
position: relative;
padding: 60% 5px;
background-color: #048990;
cursor: pointer;
transition: all 0.5s;
}
.menu > ul > li:hover {
background-color: #444;
color: white;
}
.menu > ul > li:hover + li::before,
.menu > ul > li:hover::before {
opacity: 0;
}
.menu > ul > li:active {
background-color: #444;
}
.menu >ul >li:not(:first-child)::before {
content: "";
background: #FFF;
position: absolute;
top: 0;
left: 7%;
height: 1px;
width: 86%;
}
<div class="menu">
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
Upvotes: 3