0

I'm making an hamburger menu for my website. When I click on this hamburger, I want the rest of my page to be dark.

To achieve this, I added a div :

<div id="black"></div>

My HTML :

<nav role="navigation">
    <div id="menuToggle">
      <input type="checkbox" id="mycheckbox"/>
      <span></span>
      <span></span>
      <span></span>
      <?php
        wp_nav_menu(
          array(
            'theme_location' => 'top_menu',
            'container' => 'ul', // afin d'éviter d'avoir une div autour
            'menu_class' => 'site__header__menu', // ma classe personnalisée
          )
        );
      ?>
    </div>
  </nav>
  <div id="black"></div>

This div is in display: none, and all i want is that when i click on my hamburger menu, the display style switchs to inline/block.

I tried with JavaScript :

function functionTest() {
const cb = document.querySelector('#mycheckbox');
const black = document.querySelector('#black');
  if (cb.checked) {
    black.style["display"] = "inline";
  } else {
    black.style["display"] = "none";
  }
}

It doesn't work. Thanks in advance

7
  • Show more of your html please (we need to at least see the checkbox) Commented Jan 11, 2023 at 13:34
  • Your javascript code works. Commented Jan 11, 2023 at 13:35
  • Yes but it needs to be fired from an event handler for when the checkbox is checked (or it only works the first time). Alternatively, you can do this with CSS only if you show us how your HTML is structured Commented Jan 11, 2023 at 13:36
  • I added the html code by editing my post, thanks guys ! Commented Jan 11, 2023 at 13:38
  • There is no event handler attached to anything. For example <div id="menuToggle" onclick="functionTest()"> Commented Jan 11, 2023 at 13:40

3 Answers 3

2

You can achieve this using pure CSS using the tidial selector.

#mycheckbox:checked ~ div #black {
   display:block;
}

body {background:#fff;}
#black {
  background: #ccc;
  display:none; padding:20px; position:absolute; left:0;right:0;top:30px;bottom:0;}

.opened-menu #black {display:block;}
.item,
.menu {
  display:inline-block;
  min-width:100px;
  font-size:14px;
  border:1px solid;
  padding:10px;
  text-align:center;
}

#mycheckbox:checked ~ div #black {
  display:block;
}
<input type="checkbox" id="mycheckbox"/>
<label for="mycheckbox">
Menu
</label>
<div>


<div id="black">  
  <a href="#" class="item">Item</a>  
  <a href="#" class="item">Item</a>  
  <a href="#" class=" menu">Menu</a>
</div>


</div>

Sign up to request clarification or add additional context in comments.

2 Comments

Because you cannot target all content with the input being in the place it was. Since you can hide the checkbox anyway it's the best solution to create page-wide toggles.
@BernardBorg, when I was writing the comment the OP didn't have any HTML examples in his post, only the JS function.
0

Thanks to everyone for your help. I just changed this :

<input type="checkbox" id="mycheckbox" onclick="functionTest()"/>

Jan Pfeifer said: "There is no event handler attached to anything. For example ", this solved my problem !

3 Comments

This is great, but this is not the best way to add the event listener at all. You will have a hard time refactoring this at a later date. Some of the other answers on this page are technically more elegant and make use of the browser directly instead of adding another check in JS.
Ok, I take note, I'll be back on this post to optimise my code !
Well good luck anyway! If you want to do this in JS, I would advise you to make a separate script and use something like querySelector to select the element and addEventListener to add the listener, so you don't have to be tied to JS inside your HTML.
0

If you want to do it CSS only, you can do the following. Keep in mind it does not work on Firefox or older browsers check compatibility here.

#black {
    display: none;
}

nav:has(cb:checked) + #black {
    display: inline;
}

Working in action: https://jsfiddle.net/6vwmy95L/22/

Otherwise, you can use an event listener;

const checkbox = document.querySelector("#mycheckbox");
const black = document.querySelector('#black');

if (checkbox) {
  checkbox.addEventListener("change", (event) => {
    if (event.currentTarget.checked && black) {
      black.style.display = "inline";
    } else {
      black.style.display = "none";
    }
  });
}

As @somethinghere said, if you are able to change your HTML to have a better structure and have greater browser support go for it.

If you are unable to change your HTML for some reason or another and do not need to support older browsers, you can use the :has approach.

If you are unable to change your HTML and you need to support older browsers, use the JavaScript approach.

You need the site to work even when JavaScript is disabled and support older browsers, then refactor your HTML and use @Marin HTML 's answer.

1 Comment

If you move the checkbox to the top of the body, you can target this without :has en make buttons labels which toggle the checkbox. You can then just do checkbox:checked ~ main > blabla to toggle styles for when checked. :has has, in my experience, way too little support at the moment to use. Yet.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.