Reputation: 1690
no jquery please
I have the following menu with class=menu-list, I want that on hover of nested/child ul li item, to change background color to white of parent li element
Code and working demo:
nav .menu-list{
background: white;
position: absolute;
margin-top: 60px;
padding: 12px 0;
display: none;
width: 68vw;
height: 100vh;
}
nav .menu-list li{
background: white;
display: block;
color: #000000;
position: relative;
padding: 0;
border-left: 24px white solid;
}
nav .menu-list li:hover{
background: #eee;
border-left: 24px #eee solid;
}
nav ul li:focus {
background: white;
}
nav ul li:focus ul {
display: block;
position: relative;
left: 0;
margin-left: -24px;
}
nav ul li ul li:hover {
background: white;
}
<nav>
<ul class="menu-list" style="display: block;">
<li tabindex="1" onclick="location.href='#/work'; dimScreen()">Work</li>
<li tabindex="2" onclick="dimScreen()">About
<ul>
<li onclick="location.href='#/about/what-we-do'">What we do</li>
<li onclick="location.href='#/about/how-we-work'">How we work</li>
<li onclick="location.href='#/about/leadership'">Leadership</li>
</ul>
</li>
</ul>
</nav>
Lame paint screenshot to explain better:
Upvotes: 1
Views: 2918
Reputation: 1690
Thanks everyone for trying but I only needed to add this to make it work
.menu-list li:hover {
background: #eee;
}
.menu-list li:focus {
background: white;
}
Upvotes: 2
Reputation: 777
Here's a pure CSS solution
As Tony Leigh pointed out, you cannot do exactly what you asked using pure CSS, but you can make it look like you want.
The changed lines in the CSS are commented in the snippet, and the main change in the HTML is the addition of the span tag in the top-level list elements.
The main idea is that each top-level li
remains white, while the enclosed span
turns gray on hover. That way, hovering over a sub-list doesn't change color of the parent li
.
Code Snippet
nav .menu-list{
background: white;
position: absolute;
margin-top: 60px;
padding: 12px 0;
display: none;
width: 68vw;
height: 100vh;
}
nav .menu-list li{
background: white;
display: block;
color: #000000;
position: relative;
padding: 0;
/* changed from border to background color
border-left: 24px white solid;
*/
padding-left:24px; /* added to put back the "border-left" area */
}
nav .menu-list li:hover{
background: white; /*changed from #eee to white */
/* changed from border to background color
border-left: 24px #eee solid;
*/
}
/* start added blocks */
nav .menu-list li span {
width: 100%;
display:block;
position:relative;
left:-24px;
padding-left:24px;
}
nav .menu-list li span:hover{
background: #eee;
}
/* end added blocks */
nav ul li:focus {
background: white;
}
nav ul li:focus ul {
display: block;
position: relative;
left: 0;
margin-left: -24px;
}
nav .menu-list li ul li:hover {
background: #eee;
}
<nav>
<ul class="menu-list" style="display: block;">
<li tabindex="1" onclick="location.href='#/work'; dimScreen()"><span>Work</span></li>
<li tabindex="2" onclick="dimScreen()"><span>About</span>
<ul>
<li onclick="location.href='#/about/what-we-do'">What we do</li>
<li onclick="location.href='#/about/how-we-work'">How we work</li>
<li onclick="location.href='#/about/leadership'">Leadership</li>
</ul>
</li>
</ul>
</nav>
Upvotes: 2
Reputation: 4971
First thing, you can't do this with CSS. CSS has no concept of what it's parent element is.
As for javascript, you can use mouse events. Here's an example:
var parentOn = function(e) {
e.target.parentNode.style.backgroundColor = '#9d7';
}
var parentOff = function(e) {
e.target.parentNode.style.backgroundColor = '#97a';
}
var children = document.querySelectorAll('.child');
for (var x = 0; x < children.length; x ++) {
children[x].addEventListener('mouseover', parentOn);
children[x].addEventListener('mouseout', parentOff);
};
A few things to note:
Any JavaScript DOM query will return an array of nodes, so you must iterate over them to avoid error. JQuery hides this nicely so it can be confusing.
the mouseenter and mouseleave combination is subtley different from mouseover and mouseout, you can find out more here
Working out how to use JavaScript to add and remove classes would be better than using inline styles. This answer will help. You'll be able to re-use the styles and it'll be easier to maintain - I'd such creating a utility function to handle this, like JQuery's addClass()
.
Using named function variables is a bit clearer than anonymous functions, and more re-usable.
https://jsfiddle.net/chwbuvum/6/
Upvotes: 2
Reputation: 1290
Here's a code based solution:
JS
var listElements = document.getElementsByClassName('submenu');
for (var i = 0; i < listElements.length; i++) {
listElements[i].addEventListener("mouseenter", function(evt) {
evt.target.parentNode.style.background = "red";
});
listElements[i].addEventListener("mouseleave", function(evt) {
evt.target.parentNode.style.background = "black";
});
}
HTML CHANGE
<ul class="menu-list" style="display: block;">
<li tabindex="1" onclick="location.href='#/work'; dimScreen()">Work</li>
<li tabindex="2" onclick="dimScreen()">About
<ul class='submenu'>
<li onclick="location.href='#/about/what-we-do'">What we do</li>
<li onclick="location.href='#/about/how-we-work'">How we work</li>
<li onclick="location.href='#/about/leadership'">Leadership</li>
</ul>
</li>
</ul>
As you can see, for each of your submenus you will have, I added an additional submenu
class to differentiate between the main menu and submenu. When you leave each element, it will change the background of the parent to black. When you enter, it will change it to red, based on the mouseenter
and mouseleave
events.
What it does is find the parent node and then manipulate the styling of that element.
Upvotes: 1