Why does toggling visibility works only after second click?

I have a button that should toggle between visibility visible and hidden, and even though I specify in CSS that the div has visibility: hidden, the JS code first sees the CSS as blank (as if I did not specify the style).

Only after the second click (mouseup event in my case), it detects the visibility and the toggling starts working, why?

Here’s a snippet:

let button = document.querySelector("#button");
button.addEventListener("mouseup", toggleVisibility)

function toggleVisibility() {
  let div = document.getElementById("div");
  if (div.style.visibility === "hidden") {
    div.style.visibility = "visible";
  } else {
    div.style.visibility = "hidden";
  }
}
#div {
  visibility: hidden;
}
<button id="button"> toggle </button>

<div id="div">
  <h1> Hello, World! </h1>
</div>

>Solution :

div.style reads from the style attribute not the actual applied styles. To fix this you can either use inline styling or get the computed style via getComputedStyle().

Example inline styling:


let button = document.querySelector("#button");
button.addEventListener("mouseup", toggleVisibility)

function toggleVisibility() {
  let div = document.getElementById("div");
  if (div.style.visibility === "hidden") {
    div.style.visibility = "visible";
  } else {
    div.style.visibility = "hidden";
  }
}
<button id="button"> toggle </button>

<div id="div" style="visibility: hidden;">
  <h1> Hello, World! </h1>
</div>

Example getComputedStyle():


let button = document.querySelector("#button");
button.addEventListener("mouseup", toggleVisibility)

function toggleVisibility() {
  let div = document.getElementById("div");
  const style = window.getComputedStyle(div);
  
  if (style.visibility === "hidden") {
    div.style.visibility = "visible";
  } else {
    div.style.visibility = "hidden";
  }
}
#div {
  visibility: hidden;
}
<button id="button"> toggle </button>

<div id="div">
  <h1> Hello, World! </h1>
</div>

EDIT: As pointed out in the comments toggling a class is another alternative. This is especially useful if you need to change more then one style.


let button = document.querySelector("#button");
button.addEventListener("mouseup", toggleVisibility)

function toggleVisibility() {
  let div = document.getElementById("div");
  div.classList.toggle('show');
}
#div {
  visibility: hidden;
}

#div.show {
  visibility: visible;
}
<button id="button"> toggle </button>

<div id="div">
  <h1> Hello, World! </h1>
</div>

Leave a Reply