csshoverscss-lint

How can I make an element visible on hovering an element from another section?


HTML

<nb-sidebar class="menu-sidebar>
  <nb-menu class="sidebar-menu">
     <ul class="menu-items">
        <li class="menu-item ng-tns-c140-0 ng-star-inserted" >
          <a class="ng-tns-c140-0 ng-star-inserted active" ng-reflect-router-link="/pages/dashboard"   title="Dashboard" href="/pages/dashboard">
        </li>
     </ul>
  </nb-menu>
</nb-sidebar>

<div class="content">
  <router-outlet>
    <div class="text">Message</div>
  </router-outlet>
</div>

Make router-outlet visible when I hover on li.

I tried like this

router-outlet {
  display: none;
}

nb-sidebar li:hover + .content router-outlet {
     display: block;
}

I want to do it with css/scss only. I want router-outlet to be visible when I hover on li.


Solution

  • In your example because the .content router-outlet element isn't a direct sibling of the li element the Adjacent Sibling Combinator won't work (see MDN for details)

    However there's a couple of ways of doing this. The first uses the :has() pseudo class which is neat as it doesn't need any javascript but isn't currently supported on all browsers. There's a nice introduction to this from Kevin Powell. Also caniuse.com is a good resource to check for browser compatibility.

    Note: I've added some text on your html to give you something to hover over.

    router-outlet {
      display: none;
    }
    
    /* added this */
    nb-sidebar:has(li:hover) + .content router-outlet {
         display: block;
    }
    <nb-sidebar class="menu-sidebar>
      <nb-menu class="sidebar-menu">
         <ul class="menu-items">
            <li class="menu-item ng-tns-c140-0 ng-star-inserted" >
              <a class="ng-tns-c140-0 ng-star-inserted active" ng-reflect-router-link="/pages/dashboard"   title="Dashboard" href="/pages/dashboard">This is the anchor inside the li</a>
            </li>
         </ul>
      </nb-menu>
    </nb-sidebar>
    
    <div class="content">
      <router-outlet>
        <div class="text">Message</div>
      </router-outlet>
    </div>

    The more generally supported way would be to use javascript which detects you mousing over the element then adding and removing a class to override the display: none rule as follows. The code below should be self-evident but if you have any questions just pop a comment below and I'll elaborate.

    window.onload = () => {
      const elem = document.querySelector('.menu-item');
      elem.addEventListener('mouseover', (e) => {
        document.querySelector('.content router-outlet').classList.add('display-block');
      });
    
      elem.addEventListener('mouseout', (e) => {
        document.querySelector('.content router-outlet').classList.remove('display-block');
      });
    }
    router-outlet {
      display: none;
    }
    
    .display-block {
      display: block;
    }
    <nb-sidebar class="menu-sidebar>
      <nb-menu class=" sidebar-menu ">
         <ul class="menu-items ">
            <li class="menu-item ng-tns-c140-0 ng-star-inserted " >
              <a class="ng-tns-c140-0 ng-star-inserted active " ng-reflect-router-link="/pages/dashboard "   title="Dashboard " href="/pages/dashboard ">This is the anchor inside the li</a>
            </li>
         </ul>
      </nb-menu>
    </nb-sidebar>
    
    <div class="content ">
      <router-outlet>
        <div class="text ">Message</div>
      </router-outlet>
    </div>