JorgeZ
JorgeZ

Reputation: 208

Why doesn't content hide?

I have a test HTML file in which I toggle the class 'hide' with JavaScript but the content does not hide, I can't understand why, what can be done in order to get the content to toggle between hide/show.

function init() {
  let button = document.querySelector('#menubutton');
  button.onclick = buttonClicked;
}

function buttonClicked(event) {
  let content = document.querySelector('.content');
  content.classList.toggle('hide');
}

window.addEventListener('load', init);
.hide {
  display: none;
}

.menu {
  position: relative;
}

.content {
  display: flex;
  flex-flow: column wrap;
  border: 1px solid gray;
  padding: 0.25rem;
  position: absolute;
}

.color {
  background-color: pink;
  border: 1px solid gray;
  width: 4rem;
  height: 4rem;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div class="menu">
    <div class="title">
      <button id="menubutton">Toggle</button>
    </div>
    <div class="content">
      <a href="#">Uno</a>
      <a href="#">Dos</a>
      <a href="#">Tres</a>
      <a href="#">Cuatro</a>
      <a href="#">Cinco</a>
    </div>
  </div>
  <div class="color"></div>
</body>

</html>

Upvotes: 0

Views: 48

Answers (2)

Amit Joki
Amit Joki

Reputation: 59252

When you do toggle, the classes are being toggled this way:

"content"

and

"content hide"

Now, both content and hide set display property. When there's such conflict, the rule that is defined later (either within <style> or in a further stylesheet) takes precedence.

You could see @Barmar's answer which shows !important and .content.hide to force higher precedence.

Or you could just define .hide after .content which gives it higher precedence.

function init() {
  let button = document.querySelector('#menubutton');
  button.onclick = buttonClicked;
}

function buttonClicked(event) {
  let content = document.querySelector('.content');
  content.classList.toggle('hide');
}

window.addEventListener('load', init);
.menu {
  position: relative;
}

.content {
  display: flex;
  flex-flow: column wrap;
  border: 1px solid gray;
  padding: 0.25rem;
  position: absolute;
}

.hide {
  display: none;
}

.color {
  background-color: pink;
  border: 1px solid gray;
  width: 4rem;
  height: 4rem;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div class="menu">
    <div class="title">
      <button id="menubutton">Toggle</button>
    </div>
    <div class="content">
      <a href="#">Uno</a>
      <a href="#">Dos</a>
      <a href="#">Tres</a>
      <a href="#">Cuatro</a>
      <a href="#">Cinco</a>
    </div>
  </div>
  <div class="color"></div>
</body>

</html>

Upvotes: 0

Barmar
Barmar

Reputation: 781088

When you add the hide class, the element has two classes, and they both specify different display properties. The property from .content is taking precedence.

Make your selector more specific so it will take precedence, use .content.hide.

function init() {
  let button = document.querySelector('#menubutton');
  button.onclick = buttonClicked;
}

function buttonClicked(event) {
  let content = document.querySelector('.content');
  content.classList.toggle('hide');
}

window.addEventListener('load', init);
.content.hide {
  display: none;
}

.menu {
  position: relative;
}

.content {
  display: flex;
  flex-flow: column wrap;
  border: 1px solid gray;
  padding: 0.25rem;
  position: absolute;
}

.color {
  background-color: pink;
  border: 1px solid gray;
  width: 4rem;
  height: 4rem;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div class="menu">
    <div class="title">
      <button id="menubutton">Toggle</button>
    </div>
    <div class="content">
      <a href="#">Uno</a>
      <a href="#">Dos</a>
      <a href="#">Tres</a>
      <a href="#">Cuatro</a>
      <a href="#">Cinco</a>
    </div>
  </div>
  <div class="color"></div>
</body>

</html>

Another possibility is to use !important in the .hide CSS to make it override other styles.

function init() {
  let button = document.querySelector('#menubutton');
  button.onclick = buttonClicked;
}

function buttonClicked(event) {
  let content = document.querySelector('.content');
  content.classList.toggle('hide');
}

window.addEventListener('load', init);
.hide {
  display: none !important;
}

.menu {
  position: relative;
}

.content {
  display: flex;
  flex-flow: column wrap;
  border: 1px solid gray;
  padding: 0.25rem;
  position: absolute;
}

.color {
  background-color: pink;
  border: 1px solid gray;
  width: 4rem;
  height: 4rem;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div class="menu">
    <div class="title">
      <button id="menubutton">Toggle</button>
    </div>
    <div class="content">
      <a href="#">Uno</a>
      <a href="#">Dos</a>
      <a href="#">Tres</a>
      <a href="#">Cuatro</a>
      <a href="#">Cinco</a>
    </div>
  </div>
  <div class="color"></div>
</body>

</html>

Upvotes: 1

Related Questions