1

I'm working on getting a mobile hamburger navigation to work, but I'm having trouble applying CSS to the element due to nesting/relation of the elements. I have the hamburger icon (#mobile-menu) animating properly based on the input (#nav-trigger) being checked or not (turns into an X).

But when #nav-trigger is checked, i also want to change the absolute positioning of #header-nav (bringing it into view when checked). This is where I'm stuck. How do i use CSS selectors to apply a CSS rule change to #header-nav when #nav-trigger is checked? I'm using SCSS and i've tried nesting selectors like ~, +, and more but i can't get it to work. Any help is greatly appreciated. Thank you!

<nav id="header-nav">
    <ul>
        <li>
            <a>Nav item</a>
        </li>
        <li>
            <a>Nav item</a>
        </li>
        <!-- etc... -->
    </ul>
</nav>
<div id="mobile-menu-container">
    <div id="mobile-menu-div">
        <label id="mobile-menu-label" for="nav-trigger"></label>
        <input type="checkbox" id="nav-trigger"/>
        <div id="mobile-menu"></div>
    </div>
</div>
jpsweeney94
  • 133
  • 11

1 Answers1

1

Use javascript - no broswer support (yet) to go "back" "Traversing" (parent - parent - sibling and so on) by CSS only.

div :parent :parent ~ .... no way!! :)

Related StackOverflow Q: Is there a CSS parent selector?


Basic vanilla JS example:

  var checkbox = document.querySelector("input[name=hamburger]");
  var header = document.getElementById("header-nav");
  var label = document.getElementById("mobile-menu-label");
  var checked = checkbox.checked;

  if (checked){
    // Checkbox is checked..
    header.classList.toggle('active');
    label.innerHTML = "by deafult checked";
  } else{
    label.innerHTML = "by deafult not checked";
  }

  checkbox.addEventListener( 'change', function() {
    if(this.checked) {
      // Checkbox is checked..
      header.classList.toggle('active');
      label.innerHTML = "is true";

    } else {
      // Checkbox is not checked..
      header.classList.toggle('active');
      label.innerHTML = "is false";
    }
  });
input[type=checkbox]:checked ~ #mobile-menu {
  color: white;
  background-color: magenta;
  transition: background-color 0.5s ease;
  font-style: normal;
  cursor: pointer;
} 

#header-nav.active{
  transition: background-color 0.5s ease;
  background: red;
}

label{
  cursor: pointer;
}
<nav id="header-nav">
  <ul>
    <li>
      <a>Nav item</a>
    </li>
    <li>
      <a>Nav item</a>
    </li>
    <!-- etc... -->
  </ul>
</nav>
<div id="mobile-menu-container">
  <div id="mobile-menu-div">
    <input name="hamburger" name="nav-trigger" type="checkbox" id="nav-trigger" checked/>
    <label id="mobile-menu-label" for="nav-trigger">Hello</label>
    <div id="mobile-menu">hamburger</div>
  </div>
</div>

by jquery

Use toggleClass() Method: https://www.w3schools.com/jquery/html_toggleclass.asp

Related StackOverflow Q: Jquery if checkbox is checked add a class

jQuery Traversing Methods

jQuery traversing, which means "move through", are used to "find" (or select) HTML elements based on their relation to other elements.

https://www.w3schools.com/jquery/jquery_ref_traversing.asp

Ezra Siton
  • 6,887
  • 2
  • 25
  • 37
  • Dang, too bad. Thanks for the answer but the whole reason im doing the checkbox hack is so the nav is functional without javascript. I guess ill have to restructure the nav trigger so it's a sibling of the main nav – jpsweeney94 Mar 26 '20 at 21:02
  • Anyway, you should use Javascript to toggle off/on the hamburger (Show/Hide some menu). But yes - you could change the DOM structure. One more option is to add "active" for the parent of nav trigger & main nav (and use this as a selector). .extra-wrapper.active #header-nav{ background: red; } – Ezra Siton Mar 26 '20 at 21:37