skip to Main Content

I have the following (simplified) HTML

<ul class="sidenav">
    <li class="tree-node">
        <a href="url">
            <span class="submenu-toggle-container">Text</span>
        </a>
        <ul class="accordion-menu">
            <li class="HideMenu">.......</li>
        </ul>
    </li>
    <li class="tree-node">...</li>
</ul>

I am trying to use CSS to hide the .submenu-toggle-container span when the sibling is ul li.HideMenu.

I have been able to make this work using jQuery code
$('ul.sidenav li.HideMenu').parent('ul').siblings('a').children('.submenu-toggle-container').hide(); but this is not optimal for my project and I would much rather use CSS to make this work.

My attempts include

ul.sidenav li.HideMenu ~ ul a .submenu-toggle-container {
  display: none;
}

but this does not work.

Any help is appreciated.

3

Answers


  1. Try :has

    a:has(+ ul.accordion-menu li.HideMenu) .submenu-toggle-container {
      display: none;
    }
    <ul class="sidenav">
      <li class="tree-node">
        <a href="url">
          <span class="submenu-toggle-container">Text</span>
        </a>
        <ul class="accordion-menu">
          <li class="HideMenu">.......</li>
        </ul>
      </li>
      <li class="tree-node">...</li>
    </ul>

    Does not supported by firefox if layout.css.has-selector.enabled is fasle.

    enter image description here

    Login or Signup to reply.
  2. Shuo beat me to it but you could pull this off with the :has selector:

    /*
      select .submenu-toggle-container children of
      .tree-node that has a li.HideMenu child
    */
    .tree-node:has(ul li.HideMenu) .submenu-toggle-container {
      display: none;
    }
    <ul class="sidenav">
        <li class="tree-node">
            <a href="url">
                <span class="submenu-toggle-container">Text</span>
            </a>
            <ul class="accordion-menu">
                <li class="HideMenu">.......</li>
            </ul>
        </li>
        <li class="tree-node">...</li>
    </ul>
    Login or Signup to reply.
  3. The first answer here by Shuo is the same as mine, but I’ll leave this here in case anyone wants to read more into how this solution works.

    This can be accomplished through the use of the recent :has() psuedo-class.

    Here’s a quick bit of CSS to show how it can work:

    li.tree-node a:has(+ ul.accordion-menu li.HideMenu) .submenu-toggle-container {
      background: red;
    }
    <ul class="sidenav">
        <li class="tree-node">
            <a href="url">
                <span class="submenu-toggle-container">Hide Me</span>
            </a>
            <ul class="accordion-menu">
                <li class="HideMenu">Hide Menu</li>
            </ul>
        </li>
        <li class="tree-node">...</li>
    </ul>

    I used background: red; because it’s easier to show something than to not show something, so you’d just need to replace that with display: none;

    So, how does it work?

    To start, we cannot select a parent in CSS, so we need to work through siblings. This means that the route to the .HideMenu element has to be from the a to its sibling ul and then the li. This is why we write the a:has(+ ul.accordion-menu li.HideMenu) selector.

    With the above, we’ve established the relationship through the sibling to the desired element to toggle your submenu. All that’s needed is to write the next selector to target that specific decendant.

    Great? Right! Well, beware — there is a catch: this solution is not supported in Firefox.

    To be able to do this same thing in Firefox, you will need to write JS/JQuery code to add support for this feature yourself.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search