0

Below is the code, the problem description and questions come right after.

function showOrHideMenu(menuId) {
  // alert(menuId);
  var menu = document.getElementById(menuId);
  // alert(menu);
  var isVisible = menu.style.visibility;
  // alert(isVisible);

  if ((isVisible === 'hidden') || (isVisible === '')) {
    // alert(menu1);
    menu.style.visibility = 'visible';
    menu.style.width = '75vw';
    // alert("passe 1 bis");        
  } else {
    // alert("passe 2");
    menu.style.visibility = 'hidden';
    // alert("passe 2 bis");
  }
}
@media (min-width: 800px) {
  .css_menu_1 {
    visibility: visible;
    font-size: 1.3rem;
    background-color: goldenrod;
  }
}
<img src="../images/hamburger_menu_icon.png" alt="Display or hide menu 1" class="css_btn_menu_1" id="btn_menu_1" onclick="showOrHideMenu('menu_1');">

When I am on a screen which width is less than 800px, I can click on the image.
The showOrHideMenu() function gets executed and indeed the visibility and width of the HTML element which id is menu_1 are changed as specified.
I click a second time on the image and the HTML element gets hidden as expected.
Now, if I increase the size of the viewport, the HTML element is supposed to be visible again.
Instead of it, I get a blank space.

Does the execution of the Javascript function conflict with the "execution" of the media query?
What can I do to fix that?

-- EDIT 1 --

Adding that CSS:

.css_menu_1.active 
{ 
    visibility : visible; 
    width: 75vw;
}

And replacing the Javascript by this one:

<script type="text/javascript">
    var btnMenu1 = document.getElementById('btn_menu_1');      
    var menu1 = document.getElementById('menu_1');       
    btnMenu1.addEventListener('click', () => 
    {
        menu1.classList.toggle('active');
    });
</script>

solves my problem.

Léa Massiot
  • 1,928
  • 6
  • 25
  • 43

1 Answers1

1

When you are using javascript to change styles, it adds inline style to the element. The inline styles override anything and this leads to overriding your styles defined in CSS media queries.

In this case, you can remove entirely the inline styles when menu is visible.

function showOrHideMenu(menuId) {
  var menu = document.getElementById(menuId);

  if (menu.style.visibility === 'hidden' || menu.style.visibility === '') {
    menu.style.visibility = 'visible';
    menu.style.width = '75vw';
  } else {
    menu.style.visibility = '';
    menu.style.width = '';
  }
}

Or you can add a class " active " and change the styles accordingly :

function showOrHideMenu(menuId) {
  var menu = document.getElementById(menuId);

  if (menu.style.visibility === 'hidden' || menu.style.visibility === '') {
menu.classList.add('active');
  } else {
menu.classList.remove('active');
  }
}

In css you will also have to do the following :

.css_menu_1 {
  visibility: hidden;
  width: 0;
} 
.css_menu_1.active { 
  visibility : visible; 
  width: 75vw;
}
  • Thank you for the explanation which is very clear and useful. Unfortunately, I couldn't make your solution work (the second one). Instead, I used the "toggle" mechanism. I edited my original post. – Léa Massiot Jun 14 '23 at 18:52
  • `menu.style.visibility` is always equal to `''`. So, the `if` code is the one that gets executed in all cases... – Léa Massiot Jun 15 '23 at 13:53
  • I propose the `if` test against `menu.classList.contains('active');` instead. – Léa Massiot Jun 15 '23 at 14:21