Jack
Jack

Reputation: 491

how to get display: none to work for div inside a form

UPDATE: So it seems that display:none is not working at all, when visibility:hidden is removed from the .hide class the divs show up, so it's an issue with display:none not working here.

UPDATE#2: OK so basically all the divs also have a .panel class which handles all the styling and has a display flex on it which is overriding the display:none from the .hide class. The issue now is how to give the .hide class higher priority without using !important.

     _____________________________________

In my html I have a form with a few divs inside it and each div has a button which when clicked adds a .hide class to the div and removes the .hide class from the next div, until we get to the last div and then the form is submitted with all the data.

So the HTML is basically like this:

<form> 
  <div class='panel' id='div1'></div>
  <div class='hide panel' id='div2'></div>
  <div class='hide panel' id='div3'></div>
  <div class='hide panel' id='div4'></div>
</form>

And the .hide class is:

.hide {
   display:none;
   visibility: hidden;
}

The issue I am having is that even though the divs show and dissapear properly they still seem to be on the page so that you have to scroll down a lot of empty screen space to get to the footer.

I am assuming this has something to do with the fact that the divs are inside a form and even though the div's are being set to display:none the form is still there so they arent going away.

How do I get this to work???

Thanks

Upvotes: 1

Views: 3127

Answers (4)

Rob Moll
Rob Moll

Reputation: 3453

This turns out to be a case of a CSS declaration being over-ridden by another CSS declaration which is more specific.

As in this example, a second class, .panel was applying display: flex to the div's. The user created a CSS class .hide which applied display: none. For reasons not made apparent here, the .panel declaration was more specific than the .hide declaration and as a result .hide was over-ridden.

Maybe a result of CASCADE:

Stylesheets cascade — at a very simple level, this means that the order of CSS rules matter; when two rules apply that have equal specificity the one that comes last in the CSS is the one that will be used.

And/or SPECIFICITY:

Specificity is how the browser decides which rule applies if multiple rules have different selectors, but could still apply to the same element. It is basically a measure of how specific a selector's selection will be.

And finally INHERITANCE:

Some CSS property values set on parent elements are inherited by their child elements, and some aren't.

For example, if you set a color and font-family on an element, every element inside it will also be styled with that color and font, unless you've applied different color and font values directly to them.

Ultimately the issue was discovered by observing the dev tools in the browser. The user could see that the .hide display:none declaration was lined-through indicating it was over-ridden.

The solution then becomes making the .hide CSS declaration more specific than .panel.

This was accomplished by changing the CSS declaration to:

div.hide {
   display:none;
}

MDN has a great explanation of the concept of cascade, specificity, and inheritance

At some point, you will be working on a project and you will find that the CSS you thought should be applied to an element is not working. Usually, the problem is that you have created two rules which could potentially apply to the same element. The cascade, and the closely-related concept of specificity, are mechanisms that control which rule applies when there is such a conflict. Which rule is styling your element may not be the one you expect, so you need to understand how these mechanisms work.

Upvotes: 2

Coffee Junky
Coffee Junky

Reputation: 81

With visibility: hidden, the element is not visible but still occupy the space of the web page. With display: none, the element is not visible and collapse entire.

So use display: none only to collapse the element. Don't use both.

Update: This works as can be seen here: https://jsbin.com/pegezij/edit?html,css,output

Upvotes: 1

Burham B. Soliman
Burham B. Soliman

Reputation: 1562

as long as you have two classes so you need to toggle between class like this

function toggle() {
var divs = document.querySelectorAll('.show');
for (var i = 0; i<divs.length; i++) {
divs[i].classList.toggle('hide');
}
}
.show {
display:block;
}
.hide {
display:none;
}
form {
border: 4px solid black;
}
<form> 
<div id='div1'>test</div>
<div class='show' id='div2'>1</div>
<div class='show' id='div3'>2</div>
<div class='show' id='div4'>3</div>
</form>
<input type="button" id="btn" value="toggle" onClick="toggle()" />

Upvotes: 0

Namysh
Namysh

Reputation: 4627

You just can use the hidden property like this :

const div = [...document.querySelectorAll('div')];

const firstDiv = div.shift();

firstDiv.onclick = function action(event){
  this.hidden = true;
  
  const nextDiv = div.shift();
  
  if(nextDiv) {
    nextDiv.hidden = false;
    nextDiv.onclick = action;
    event.preventDefault();
  } else {
    // no preventDefault here for submitting the form
  }
}
form {
  border: 1px solid black;
}
<form> 
  <div id='div1'>1: <button>Hide</button></div>
  <div id='div2' hidden >2: <button>Hide</button></div>
  <div id='div3' hidden >3: <button>Hide</button></div>
  <div id='div4' hidden >4: <button>Hide</button></div>
</form>

As you can see the form's height stay the same. You can use indexes instead of shifting the array.

More reading here

Upvotes: 0

Related Questions