Reputation: 491
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
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
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
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
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.
Upvotes: 0