Is it possible to use an html element class as a condition for if statement or relative way in sass css?
In many cases in programming it is necessary to combine a loop and an if test to check if something is in the desired state, and if it is then increase the value that will be used. I was wondering if this could be done in scss?
First of all I know I can do it with JS, so please don't post js related answers here - just wondering if it can be done with SCSS or SASS and have just pure CSS
Why I want to do this? I have a dropdown menu with multiple options, but some products have fewer options than others and the list changes dynamically. So I'm adding a class ".hidden" to options that shouldn't be visible.
Each option has a button and a list that appears when you hover over the button. What I want to do is to level all the lists to the bottom line, but for this I have to apply the "bottom" style with the multiplication of 100% of the relative parent height style, but only to the element without the ".hidden" class.
my html looks something like this:
<ul class="dropdown-menu components" role="dropdown">
<li class="dropdown-item hidden"> <!-- pass $c increasment -->
<button class="btn icon"></button>
<div class="list"></div>
</li>
<li class="dropdown-item"> <!-- $c = 4 -->
<button class="btn icon"></button>
<div class="list"></div> <!-- bottom: calc(-400% - 2rem) -->
</li>
<li class="dropdown-item hidden"> <!-- pass $c increasment -->
<button class="btn icon"></button>
<div class="list"></div>
</li>
<li class="dropdown-item"> <!-- $c = 3 -->
<button class="btn icon"></button>
<div class="list"></div> <!-- bottom: calc(-300% - 2rem) -->
</li>
<li class="dropdown-item"> <!-- $c = 2 -->
<button class="btn icon"></button>
<div class="list"></div> <!-- bottom: calc(-200% - 2rem) -->
</li>
<li class="dropdown-item hidden"> <!-- pass $c increasment -->
<button class="btn icon"></button>
<div class="list"></div>
</li>
<li class="dropdown-item"> <!-- $c = 1 -->
<button class="btn icon"></button>
<div class="list"></div> <!-- bottom: calc(-100% - 2rem) -->
</li>
</ul>
I was hoping something as logical as this would work:
$elements: 10;
$c:0;
@for $i from 0 to $elements {
&:not(.hidden){
$c: $c + 1;
&:nth-last-child(#{$c}){
.list{
bottom: calc(calc(-100% * #{$c}) - 2rem);
}
}
}
}
However, the scss "for" statement seems to ignore the "&:not(.hidden)" and increment $c with each iteration.
Obviously, I can do this with JS when adding the ".hidden" class, but I will have to loop throu all the objects every time, and was wondering if it could be done in a more efficient and convenient way with CSS?
However, if anyone is interested how to do it in JS than:
function CheckAlignAllOptionLists(){
let _menu = document.querySelector(".dropdown-menu.components");
if(_menu == null){ return;}
let _options = _menu.querySelectorAll(".dropdown-item");
let _hidden = _menu.querySelectorAll(".dropdown-item.hidden");
let _count = _options.length - _hidden.length; // we want to trigger children counting from bottom to top but in html li elements by default are one after or under another...
// if you use flex-direction: column-reverse; than you can just write let _count = 0 and later on _count++;
_options.forEach((_o)=>{
let _list = _o.querySelector(".list");
if(_list != null){
_list.style.bottom = "0px";
if(!_o.classList.contains("hidden")){
_count--;
_list.style.bottom = "calc(calc(-100% * "+_count+") - 2rem)";
}
}
});
}