shadow0359 shadow0359 - 3 months ago 7
CSS Question

Dropdown using css and javascript not working when internal css position is swapped

This works

.c1
{
background-color:red;
position:relative;
}
.c2
{
background-color:blue;
position:absolute;
height:50px;
width:100px;
display:none;}

.show
{
display:block;
}

<body>
<button class="c1" onclick="myfunction()">click</button>
<div id="change" class="c2">drop </div>

<script>
function myfunction(){
document.getElementById("change").classList.toggle("show")
}
</script>


but swap .show and .c2,It will not work.

.c1
{
background-color:red;
position:relative;
}
.show
{
display:block;
}

.c2
{
background-color:blue;
position:absolute;
height:50px;
width:100px;
display:none;}



<body>
<button class="c1" onclick="myfunction()">click</button>
<div id="change" class="c2">drop </div>

<script>
function myfunction(){
document.getElementById("change").classList.toggle("show")
}
</script>


It might be because of classList.toggle which i have used.

It changes display of division from none to block.
only code change is the .c2 class and .show class position.
Does it matter in which order the css classes are?

Answer

Maybe it looks strange it first sight, but it is actually quite logical if you think of how css orders the declarations, which is called specificity. For every front-end developer it would be good to at least once read the excellent and extensive guide at MDN.

From the guide:

Specificity is the means by which browsers decide which CSS property values are the most relevant to an element and, therefore, will be applied. Specificity is based on the matching rules which are composed of CSS selectors of different sorts.

For example, declarations further down the bottom of your document have a higher precedence, and these will applied. For example if you have the declarations below, your background will be blue.

body { background: red; }
...
body { background: blue; }

But the more specific you are, the more important it is, and the more specific declaration will be applied. So althought a bit counterintuitive at first, with the code below your background will actually be red:

html body { background: red; }
...
body { background: blue; }

Back to your example: an element with class .show should be displayed as a block element, but if you have the declaration of that class before the declaration of another class which is applied to the same element (.c2 in this case), it will get overridden. You can however override that by being more specific:

.c2.show { display: block; }
.c2 { display: none; }

<div class="c2"><!-- This element is hidden --></div>
<div class="c2 show"><!-- This element is shown --></div>

You should try to avoid !important whenever possible, as it can make it unclear sometimes why a css declaration is applied, and it's more difficult to override it. And basically, it's almost never necessary.