Home > Mobile >  Using child selectors to switch display values CSS
Using child selectors to switch display values CSS

Time:09-26

I have a modal that, when opened, makes everything disappear via display-none except for itself. Or, at least, that's what I want it to do, but it doesn't. I don't know much about child selectors, but I think this should work since .fixed#myNav is a direct child of .fixed#all-body. Does anybody know what could be wrong?

#all-body {
    display: block;
}
#myNav {
    display: none;
}

.fixed#all-body >:not(.fixed#myNav),
.fixed#all-body >:not(.fixed#myNav) * {
    display: none !important;
}
<body id="all-body">
    <div class="site-header">
        <button onclick="toggleMobileMenu()">Open menu</button>
        <!-- Other header content-->
    </div>
    <div id="myNav">
        <button onclick="toggleMobileMenu()">Close menu</button>
        <!-- Other menu content-->
    </div>
    <!-- Other page content-->
</body>
function toggleMobileMenu() {
  var element = document.getElementById("myNav");
  element.classList.toggle("fixed");
  var element = document.getElementById("all-body");
  element.classList.toggle("fixed");
}

More context, if anybody's wondering: When the button to open the modal is clicked, the .fixed class is added to both #all-body and #myNav, and I want their respective display values to switch. However, since #myNav is a child of #all-body, this doesn't work. I'm hoping to use the code above to basically say "everything except for #myNav is at display: none."

CodePudding user response:

function toggleMobileMenu() {
  var element = document.getElementById("all-body");
  element.classList.toggle("fixed");
}
#all-body {
    display: block;
}
#myNav {
    display: none;
}

.fixed #myNav{
  display:block;
}

.fixed#all-body >:not(#myNav) {
    display: none !important;
}
<body id="all-body">
    <div class="site-header">
        <button onclick="toggleMobileMenu()">Open menu</button>
        <!-- Other header content-->
    </div>
    <div id="myNav">
        <button onclick="toggleMobileMenu()">Close menu</button>
        menu
    </div>
  <p>page content</p>
</body>

.fixed class is set for body only.

Added display:block for nav when .fixed is parent.

Content should be wrapped in a tag for this to work.

CodePudding user response:

I found it easier to follow what was going on if there was just one class, showMenu, introduced rather than trying to use fixed twice.

What this snippet does is toggle showMenu on the body. It also ensures the 'other content' on the page is wrapped in an element so that it too can respond when the showMenu class is added to body.

Then it does what you were basically doing, set all child elements of body to display none when the showMenu class is set and then it sets the menu to block so it alone shows.

function toggleMobileMenu() {
  var element = document.getElementById("all-body");
  element.classList.toggle("showMenu");
}
#myNav {
  display: none;
}


/* stop showing every element below body (but not body itself) */

.showMenu>:not(#myNav) {
  display: none;
}


/* override the above setting for just the menu */

.showMenu #myNav {
  display: block;
}
<body id="all-body">
  <div class="site-header">
    <button onclick="toggleMobileMenu()">Open menu</button>
    <!-- Other header content-->
  </div>
  <div id="myNav">
    <button onclick="toggleMobileMenu()">Close menu</button> Other menu content
  </div>
  <div>
    Other page content
  </div>

I couldn't see how to do it without making sure the other content is in its own element - if it isn't it will stay visible which I believe you don't want.

  •  Tags:  
  • css
  • Related