如何在hover主容器内ul/li时修改非同级div的CSS样式
Got it, let's break this down for you. The issue here is that pure CSS can't handle this scenario—CSS doesn't have a way to select sibling elements of a parent when hovering a child element (since there's no parent selector or upward traversal in CSS). So we'll need to use JavaScript to make this work, while keeping your existing HTML structure intact.
Approach: Event Delegation with JavaScript
We'll use event delegation on the .container-main element to listen for hover events on its inner <ul> or <li> elements, then toggle a custom class on .container1 and .container2 to apply your desired styles.
Step 1: Add CSS for the Hover State
First, define the styles you want to apply to .container1 and .container2 when the inner list elements are hovered. We'll use a custom class for this:
/* Define your hover styles here */ .hover-active { background-color: red; color: white; padding: 10px; /* Add any other styles you need */ }
Step 2: Implement the JavaScript
Use event delegation to efficiently listen for hover events, check if the hovered element is a <ul> or <li>, then toggle the class on the target containers:
// Grab the main container and the two target containers const mainContainer = document.querySelector('.container-main'); const targetContainers = document.querySelectorAll('.container1, .container2'); // Handle mouse entering the ul/li elements mainContainer.addEventListener('mouseover', (e) => { // Check if the hovered element is either a UL or LI const isTargetElement = e.target.tagName === 'UL' || e.target.tagName === 'LI'; if (isTargetElement) { targetContainers.forEach(container => { container.classList.add('hover-active'); }); } }); // Handle mouse leaving the ul/li elements mainContainer.addEventListener('mouseout', (e) => { const isTargetElement = e.target.tagName === 'UL' || e.target.tagName === 'LI'; if (isTargetElement) { targetContainers.forEach(container => { container.classList.remove('hover-active'); }); } });
Why This Works
- Event Delegation: Instead of adding event listeners to every single
<li>and<ul>, we listen on their parent.container-main. This is more efficient, especially if you add more list items later. - Target Check: We verify that the element triggering the event is actually a
<ul>or<li>so we don't apply styles when hovering other parts of.container-main. - Class Toggle: Using a CSS class keeps your styles separated from your JavaScript, making it easier to modify styles later.
Alternative: Adjust HTML Structure (If Possible)
If you're open to modifying your HTML, you could wrap .container1 and .container2 inside a shared parent container with .container-main. Then you could use CSS sibling selectors, but note this would trigger when hovering any part of .container-main (not just the ul/li):
<div class="wrapper"> <div class="container-main"> <div class="container-inner"> <ul class="list"> <li>Option 1</li> <li>Option 2</li> </ul> </div> </div> <div class="container1"> <p>Container text</p> </div> <div class="container2"> <p>Container text</p> </div> </div>
Corresponding CSS:
.container-main:hover ~ .container1, .container-main:hover ~ .container2 { background-color: red; }
But since your requirement is to only trigger when hovering the ul/li, the JavaScript approach is still the best fit.
内容的提问来源于stack exchange,提问作者Merlin2ify

